Initial checking of Gob engine
svn-id: r17388
This commit is contained in:
parent
b399a052f1
commit
1758c5b211
50 changed files with 15896 additions and 2 deletions
|
@ -81,6 +81,12 @@ else
|
||||||
MODULES += kyra
|
MODULES += kyra
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef DISABLE_GOB
|
||||||
|
DEFINES += -DDISABLE_GOB
|
||||||
|
else
|
||||||
|
MODULES += gob
|
||||||
|
endif
|
||||||
|
|
||||||
# After the game specific modules follow the shared modules
|
# After the game specific modules follow the shared modules
|
||||||
MODULES += \
|
MODULES += \
|
||||||
gui \
|
gui \
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ For a more comprehensive changelog for the latest experimental CVS code, see:
|
||||||
New Games:
|
New Games:
|
||||||
- Added SAGA engine (for the games and "I Have No Mouth and I Must Scream"
|
- Added SAGA engine (for the games and "I Have No Mouth and I Must Scream"
|
||||||
and "Inherit the Earth").
|
and "Inherit the Earth").
|
||||||
|
- Added Gob engine (for Goblins series)
|
||||||
|
|
||||||
General:
|
General:
|
||||||
- Reworked cursor handling in SDL backend. Now cursors can have their own
|
- Reworked cursor handling in SDL backend. Now cursors can have their own
|
||||||
|
|
|
@ -278,9 +278,11 @@ void PluginManager::loadPlugins() {
|
||||||
#ifndef DISABLE_KYRA
|
#ifndef DISABLE_KYRA
|
||||||
LINK_PLUGIN(KYRA)
|
LINK_PLUGIN(KYRA)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DISABLE_GOB
|
||||||
|
LINK_PLUGIN(GOB)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManager::unloadPlugins() {
|
void PluginManager::unloadPlugins() {
|
||||||
|
|
|
@ -155,5 +155,4 @@ public:
|
||||||
DetectedGameList detectGames(const FSList &fslist) const;
|
DetectedGameList detectGames(const FSList &fslist) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
13
configure
vendored
13
configure
vendored
|
@ -30,6 +30,7 @@ _build_sword2=yes
|
||||||
_build_queen=yes
|
_build_queen=yes
|
||||||
_build_kyra=no
|
_build_kyra=no
|
||||||
_build_saga=yes
|
_build_saga=yes
|
||||||
|
_build_gob=no
|
||||||
_need_memalign=no
|
_need_memalign=no
|
||||||
_build_plugins=no
|
_build_plugins=no
|
||||||
_nasm=auto
|
_nasm=auto
|
||||||
|
@ -268,6 +269,7 @@ Optional Features:
|
||||||
--disable-queen don't build the Flight of the Amazon Queen engine
|
--disable-queen don't build the Flight of the Amazon Queen engine
|
||||||
--disable-saga don't build the SAGA engine
|
--disable-saga don't build the SAGA engine
|
||||||
--enable-kyra build the Legend of Kyrandia engine
|
--enable-kyra build the Legend of Kyrandia engine
|
||||||
|
--enable-gob build the Gobli*ns engine
|
||||||
--enable-plugins build engines as loadable modules instead of
|
--enable-plugins build engines as loadable modules instead of
|
||||||
static linking them
|
static linking them
|
||||||
--disable-mt32emu don't enable the integrated MT-32 emulator
|
--disable-mt32emu don't enable the integrated MT-32 emulator
|
||||||
|
@ -322,6 +324,7 @@ for ac_option in $@; do
|
||||||
--disable-queen) _build_queen=no ;;
|
--disable-queen) _build_queen=no ;;
|
||||||
--disable-saga) _build_saga=no ;;
|
--disable-saga) _build_saga=no ;;
|
||||||
--enable-kyra) _build_kyra=yes ;;
|
--enable-kyra) _build_kyra=yes ;;
|
||||||
|
--enable-gob) _build_gob=yes ;;
|
||||||
--enable-alsa) _alsa=yes ;;
|
--enable-alsa) _alsa=yes ;;
|
||||||
--disable-alsa) _alsa=no ;;
|
--disable-alsa) _alsa=no ;;
|
||||||
--enable-vorbis) _vorbis=yes ;;
|
--enable-vorbis) _vorbis=yes ;;
|
||||||
|
@ -581,6 +584,12 @@ else
|
||||||
_mak_saga='# DISABLE_SAGA = 1'
|
_mak_saga='# DISABLE_SAGA = 1'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$_build_gob" = no ; then
|
||||||
|
_mak_gob='DISABLE_GOB = 1'
|
||||||
|
else
|
||||||
|
_mak_gob='# DISABLE_GOB = 1'
|
||||||
|
fi
|
||||||
|
|
||||||
if test -n "$_host"; then
|
if test -n "$_host"; then
|
||||||
# Cross-compiling mode - add your target here if needed
|
# Cross-compiling mode - add your target here if needed
|
||||||
case "$_host" in
|
case "$_host" in
|
||||||
|
@ -1041,6 +1050,9 @@ fi
|
||||||
if test "$_build_kyra" = yes ; then
|
if test "$_build_kyra" = yes ; then
|
||||||
echo " Legend of Kyrandia"
|
echo " Legend of Kyrandia"
|
||||||
fi
|
fi
|
||||||
|
if test "$_build_gob" = yes ; then
|
||||||
|
echo " Gobli*ns"
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
@ -1166,6 +1178,7 @@ $_mak_sword2
|
||||||
$_mak_queen
|
$_mak_queen
|
||||||
$_mak_kyra
|
$_mak_kyra
|
||||||
$_mak_saga
|
$_mak_saga
|
||||||
|
$_mak_gob
|
||||||
$_mak_mt32emu
|
$_mak_mt32emu
|
||||||
|
|
||||||
INCLUDES += $INCLUDES
|
INCLUDES += $INCLUDES
|
||||||
|
|
20
gob/anim.cpp
Normal file
20
gob/anim.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/anim.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 anim_animAreaLeft;
|
||||||
|
int16 anim_animAreaTop;
|
||||||
|
int16 anim_animAreaWidth;
|
||||||
|
int16 anim_animAreaHeight;
|
||||||
|
SurfaceDesc *anim_underAnimSurf = 0;
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
21
gob/anim.h
Normal file
21
gob/anim.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __ANIM_H
|
||||||
|
#define __ANIM_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
extern int16 anim_animAreaLeft;
|
||||||
|
extern int16 anim_animAreaTop;
|
||||||
|
extern int16 anim_animAreaWidth;
|
||||||
|
extern int16 anim_animAreaHeight;
|
||||||
|
extern SurfaceDesc *anim_underAnimSurf;
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
356
gob/dataio.cpp
Normal file
356
gob/dataio.cpp
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/dataio.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/pack.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 file_write(int16 handle, char *buf, int16 size) {
|
||||||
|
return filesHandles[handle].write(buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 file_open(const char *path, File::AccessMode mode) {
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FILES; i++) {
|
||||||
|
if (!filesHandles[i].isOpen())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == MAX_FILES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
filesHandles[i].open(path, mode);
|
||||||
|
|
||||||
|
if (filesHandles[i].isOpen())
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
File *file_getHandle(int16 handle) {
|
||||||
|
return &filesHandles[handle];
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 data_getChunk(const char *chunkName) {
|
||||||
|
int16 file;
|
||||||
|
int16 slot;
|
||||||
|
int16 chunk;
|
||||||
|
struct ChunkDesc *dataDesc;
|
||||||
|
|
||||||
|
for (file = 0; file < MAX_DATA_FILES; file++) {
|
||||||
|
if (dataFiles[file] == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
|
||||||
|
if (chunkPos[file * MAX_SLOT_COUNT + slot] == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (slot == MAX_SLOT_COUNT)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
dataDesc = dataFiles[file];
|
||||||
|
for (chunk = 0; chunk < numDataChunks[file];
|
||||||
|
chunk++, dataDesc++) {
|
||||||
|
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 0;
|
||||||
|
chunkSize[file * MAX_SLOT_COUNT + slot] =
|
||||||
|
dataDesc->size;
|
||||||
|
chunkOffset[file * MAX_SLOT_COUNT + slot] =
|
||||||
|
dataDesc->offset;
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot] = 0;
|
||||||
|
return file * 10 + slot + 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char data_freeChunk(int16 handle) {
|
||||||
|
if (handle >= 50 && handle < 100) {
|
||||||
|
handle -= 50;
|
||||||
|
chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 data_readChunk(int16 handle, char *buf, int16 size) {
|
||||||
|
int16 file;
|
||||||
|
int16 slot;
|
||||||
|
int16 i;
|
||||||
|
int32 offset;
|
||||||
|
|
||||||
|
if (handle < 50 || handle >= 100)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
file = (handle - 50) / 10;
|
||||||
|
slot = (handle - 50) % 10;
|
||||||
|
if (isCurrentSlot[file * MAX_SLOT_COUNT + slot] == 0) {
|
||||||
|
for (i = 0; i < MAX_SLOT_COUNT; i++)
|
||||||
|
isCurrentSlot[file * MAX_SLOT_COUNT + i] = 0;
|
||||||
|
|
||||||
|
offset =
|
||||||
|
chunkOffset[file * MAX_SLOT_COUNT + slot] +
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot];
|
||||||
|
debug(0, "seek: %ld, %ld", chunkOffset[file * MAX_SLOT_COUNT + slot], chunkPos[file * MAX_SLOT_COUNT + slot]);
|
||||||
|
file_getHandle(dataFileHandles[file])->seek(offset, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 1;
|
||||||
|
if (chunkPos[file * MAX_SLOT_COUNT + slot] + size >
|
||||||
|
chunkSize[file * MAX_SLOT_COUNT + slot])
|
||||||
|
size =
|
||||||
|
chunkSize[file * MAX_SLOT_COUNT + slot] -
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot];
|
||||||
|
|
||||||
|
file_getHandle(dataFileHandles[file])->read(buf, size);
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot] += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 data_seekChunk(int16 handle, int32 pos, int16 from) {
|
||||||
|
int16 file;
|
||||||
|
int16 slot;
|
||||||
|
|
||||||
|
if (handle < 50 || handle >= 100)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
file = (handle - 50) / 10;
|
||||||
|
slot = (handle - 50) % 10;
|
||||||
|
isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 0;
|
||||||
|
if (from == SEEK_SET)
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot] = pos;
|
||||||
|
else
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + slot] += pos;
|
||||||
|
|
||||||
|
return chunkPos[file * MAX_SLOT_COUNT + slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 data_getChunkSize(const char *chunkName) {
|
||||||
|
int16 file;
|
||||||
|
int16 chunk;
|
||||||
|
struct ChunkDesc *dataDesc;
|
||||||
|
int16 slot;
|
||||||
|
int32 realSize;
|
||||||
|
|
||||||
|
for (file = 0; file < MAX_DATA_FILES; file++) {
|
||||||
|
if (dataFiles[file] == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
dataDesc = dataFiles[file];
|
||||||
|
for (chunk = 0; chunk < numDataChunks[file];
|
||||||
|
chunk++, dataDesc++) {
|
||||||
|
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dataDesc->packed == 0) {
|
||||||
|
packedSize = -1;
|
||||||
|
return dataDesc->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
|
||||||
|
isCurrentSlot[slot] = 0;
|
||||||
|
|
||||||
|
file_getHandle(dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET);
|
||||||
|
realSize = file_getHandle(dataFileHandles[file])->readUint32LE();
|
||||||
|
packedSize = dataDesc->size;
|
||||||
|
return realSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_openDataFile(const char *src) {
|
||||||
|
char path[128];
|
||||||
|
int16 i;
|
||||||
|
int16 file;
|
||||||
|
struct ChunkDesc *dataDesc;
|
||||||
|
|
||||||
|
strcpy(path, src);
|
||||||
|
for (i = 0; path[i] != '.' && path[i] != 0; i++);
|
||||||
|
if (path[i] == 0)
|
||||||
|
strcat(path, ".stk");
|
||||||
|
|
||||||
|
for (file = 0; file < MAX_DATA_FILES; file++)
|
||||||
|
if (dataFiles[file] == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (file == MAX_DATA_FILES)
|
||||||
|
error("data_dataFileOpen: Data file slots are full\n");
|
||||||
|
dataFileHandles[file] = file_open(path);
|
||||||
|
|
||||||
|
if (dataFileHandles[file] == -1)
|
||||||
|
error("data_dataFileOpen: Can't open %s data file\n", path);
|
||||||
|
|
||||||
|
numDataChunks[file] = file_getHandle(dataFileHandles[file])->readUint16LE();
|
||||||
|
|
||||||
|
debug(0, "DataChunks: %d [for %s]", numDataChunks[file], path);
|
||||||
|
|
||||||
|
dataFiles[file] = dataDesc =
|
||||||
|
(struct ChunkDesc *)malloc(sizeof(struct ChunkDesc) *
|
||||||
|
numDataChunks[file]);
|
||||||
|
|
||||||
|
for (i = 0; i < numDataChunks[file]; i++) {
|
||||||
|
file_getHandle(dataFileHandles[file])->read(dataDesc[i].chunkName, 13);
|
||||||
|
dataDesc[i].size = file_getHandle(dataFileHandles[file])->readUint32LE();
|
||||||
|
dataDesc[i].offset = file_getHandle(dataFileHandles[file])->readUint32LE();
|
||||||
|
dataDesc[i].packed = file_getHandle(dataFileHandles[file])->readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numDataChunks[file]; i++)
|
||||||
|
debug(0, "%d: %s %d", i, dataDesc[i].chunkName, dataDesc[i].size);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_SLOT_COUNT; i++)
|
||||||
|
chunkPos[file * MAX_SLOT_COUNT + i] = -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_closeDataFile() {
|
||||||
|
int16 file;
|
||||||
|
for (file = MAX_DATA_FILES - 1; file >= 0; file--) {
|
||||||
|
if (dataFiles[file] != 0) {
|
||||||
|
free((char *)dataFiles[file]);
|
||||||
|
dataFiles[file] = 0;
|
||||||
|
file_getHandle(dataFileHandles[file])->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *data_getUnpackedData(const char *name) {
|
||||||
|
int32 realSize;
|
||||||
|
int16 chunk;
|
||||||
|
char *unpackBuf;
|
||||||
|
char *packBuf;
|
||||||
|
char *ptr;
|
||||||
|
int32 sizeLeft;
|
||||||
|
|
||||||
|
realSize = data_getChunkSize(name);
|
||||||
|
if (packedSize == -1 || realSize == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
chunk = data_getChunk(name);
|
||||||
|
if (chunk == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unpackBuf = (char *)malloc(realSize);
|
||||||
|
if (unpackBuf == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
packBuf = (char *)malloc(packedSize);
|
||||||
|
if (packBuf == 0) {
|
||||||
|
free(unpackBuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sizeLeft = packedSize;
|
||||||
|
ptr = packBuf;
|
||||||
|
while (sizeLeft > 0x4000) {
|
||||||
|
data_readChunk(chunk, (char *)ptr, 0x4000);
|
||||||
|
sizeLeft -= 0x4000;
|
||||||
|
ptr += 0x4000;
|
||||||
|
}
|
||||||
|
data_readChunk(chunk, (char *)ptr, sizeLeft);
|
||||||
|
data_freeChunk(chunk);
|
||||||
|
unpackData((char *)packBuf, (char *)unpackBuf);
|
||||||
|
free(packBuf);
|
||||||
|
return unpackBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_closeData(int16 handle) {
|
||||||
|
if (data_freeChunk(handle) != 0)
|
||||||
|
file_getHandle(handle)->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 data_openData(const char *path, File::AccessMode mode) {
|
||||||
|
int16 handle;
|
||||||
|
|
||||||
|
if (mode != File::kFileReadMode)
|
||||||
|
return file_open(path, mode);
|
||||||
|
|
||||||
|
handle = data_getChunk(path);
|
||||||
|
if (handle >= 0)
|
||||||
|
return handle;
|
||||||
|
|
||||||
|
return file_open(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 data_readData(int16 handle, char *buf, int16 size) {
|
||||||
|
int32 res;
|
||||||
|
|
||||||
|
res = data_readChunk(handle, buf, size);
|
||||||
|
if (res >= 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return file_getHandle(handle)->read(buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_seekData(int16 handle, int32 pos, int16 from) {
|
||||||
|
int32 resPos;
|
||||||
|
|
||||||
|
resPos = data_seekChunk(handle, pos, from);
|
||||||
|
if (resPos != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
file_getHandle(handle)->seek(pos, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 data_getDataSize(const char *name) {
|
||||||
|
char buf[128];
|
||||||
|
int32 chunkSz;
|
||||||
|
struct stat statBuf;
|
||||||
|
|
||||||
|
strcpy(buf, name);
|
||||||
|
chunkSz = data_getChunkSize(buf);
|
||||||
|
if (chunkSz >= 0)
|
||||||
|
return chunkSz;
|
||||||
|
|
||||||
|
if (stat(buf, &statBuf) == -1)
|
||||||
|
error("data_getDataSize: Can't find data (%s)", name);
|
||||||
|
|
||||||
|
return statBuf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *data_getData(const char *path) {
|
||||||
|
char *data;
|
||||||
|
char *ptr;
|
||||||
|
int32 size;
|
||||||
|
int16 handle;
|
||||||
|
|
||||||
|
data = data_getUnpackedData(path);
|
||||||
|
if (data != 0)
|
||||||
|
return data;
|
||||||
|
|
||||||
|
size = data_getDataSize(path);
|
||||||
|
data = (char *)malloc(size);
|
||||||
|
if (data == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
handle = data_openData(path);
|
||||||
|
|
||||||
|
ptr = data;
|
||||||
|
while (size > 0x4000) {
|
||||||
|
data_readData(handle, (char *)ptr, 0x4000);
|
||||||
|
size -= 0x4000;
|
||||||
|
ptr += 0x4000;
|
||||||
|
}
|
||||||
|
data_readData(handle, (char *)ptr, size);
|
||||||
|
data_closeData(handle);
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char *data_getSmallData(const char *path) {
|
||||||
|
return data_getData(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
46
gob/dataio.h
Normal file
46
gob/dataio.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __DATAIO_H
|
||||||
|
#define __DATAIO_H
|
||||||
|
|
||||||
|
#include "common/file.h"
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#define MAX_DATA_FILES 3
|
||||||
|
#define MAX_SLOT_COUNT 4
|
||||||
|
|
||||||
|
struct ChunkDesc {
|
||||||
|
char chunkName[13];
|
||||||
|
uint32 size;
|
||||||
|
uint32 offset;
|
||||||
|
byte packed;
|
||||||
|
};
|
||||||
|
|
||||||
|
int16 file_open(const char *path, File::AccessMode mode = File::kFileReadMode);
|
||||||
|
File *file_getHandle(int16 handle);
|
||||||
|
int16 data_getChunk(const char *chunkName);
|
||||||
|
char data_freeChunk(int16 handle);
|
||||||
|
int32 data_readChunk(int16 handle, char *buf, int16 size);
|
||||||
|
int16 data_seekChunk(int16 handle, int32 pos, int16 from);
|
||||||
|
int32 data_getChunkSize(const char *chunkName);
|
||||||
|
void data_openDataFile(const char *src);
|
||||||
|
void data_closeDataFile(void);
|
||||||
|
char *data_getUnpackedData(const char *name);
|
||||||
|
void data_closeData(int16 handle);
|
||||||
|
int16 data_openData(const char *path, File::AccessMode mode = File::kFileReadMode);
|
||||||
|
int32 data_readData(int16 handle, char *buf, int16 size);
|
||||||
|
void data_seekData(int16 handle, int32 pos, int16 from);
|
||||||
|
int32 data_getDataSize(const char *name);
|
||||||
|
char *data_getData(const char *path);
|
||||||
|
char *data_getSmallData(const char *path);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
171
gob/debug.cpp
Normal file
171
gob/debug.cpp
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/scenery.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
static int16 logFile = -2;
|
||||||
|
static char buf[256];
|
||||||
|
|
||||||
|
extern uint32 always0_dword_23EC_560;
|
||||||
|
|
||||||
|
static void log_close(void) {
|
||||||
|
if (logFile != -2)
|
||||||
|
close(logFile);
|
||||||
|
logFile = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_init(void) {
|
||||||
|
if (logFile == -2) {
|
||||||
|
logFile = open(LOG_NAME, O_WRONLY | O_CREAT);
|
||||||
|
if (logFile != -1)
|
||||||
|
atexit(&log_close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_write(const char *format, ...) {
|
||||||
|
va_list lst;
|
||||||
|
va_start(lst, format);
|
||||||
|
|
||||||
|
log_init();
|
||||||
|
if (logFile >= 0) {
|
||||||
|
vsprintf(buf, format, lst);
|
||||||
|
write(logFile, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_printInt(int16 val) {
|
||||||
|
log_write("dbg_printInt: %d\n", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_printPtr(void *ptr) {
|
||||||
|
log_write("dbg_printPtr: %p\n", ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_printStr(char *str) {
|
||||||
|
log_write("dbg_printStr: ");
|
||||||
|
log_write(str);
|
||||||
|
log_write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_dumpMem(char *ptr, int16 size) {
|
||||||
|
int16 i;
|
||||||
|
log_write("dbg_dumpMem %p %d:", ptr, size);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
log_write("%02x ", (uint16)(byte)ptr[i]);
|
||||||
|
log_write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_dumpMemChars(char *ptr, int16 size) {
|
||||||
|
int16 i;
|
||||||
|
log_write("dbg_dumpMem %p %ld:", ptr, size);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
log_write("%c ", ptr[i]);
|
||||||
|
log_write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_printDelim() {
|
||||||
|
log_write("-------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_printHexInt(int16 val) {
|
||||||
|
log_write("%02x\n", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_dumpStaticScenery(Scen_Static * st) {
|
||||||
|
int16 i, j;
|
||||||
|
Scen_StaticPlane *ptr;
|
||||||
|
|
||||||
|
log_write("dbg_dumpStaticScenery\n");
|
||||||
|
log_write("----------\n");
|
||||||
|
log_write("Layers count = %d\n", st->layersCount);
|
||||||
|
|
||||||
|
for (i = 0; i < st->layersCount; i++) {
|
||||||
|
log_write("Layer %d:\n", i);
|
||||||
|
log_write("Back sprite resource id = %d\n",
|
||||||
|
st->layers[i]->backResId);
|
||||||
|
log_write("Plane count = %d\n", st->layers[i]->planeCount);
|
||||||
|
|
||||||
|
for (j = 0; j < st->layers[i]->planeCount; j++) {
|
||||||
|
ptr = &st->layers[i]->planes[j];
|
||||||
|
log_write
|
||||||
|
("Plane %d: pictIndex = %d, pieceIndex = %d, drawOrder = %d\n",
|
||||||
|
j, (int16)ptr->pictIndex, (int16)ptr->pieceIndex,
|
||||||
|
(int16)ptr->drawOrder);
|
||||||
|
|
||||||
|
log_write
|
||||||
|
("destX = %d, destY = %d, transparency = %d\n",
|
||||||
|
ptr->destX, ptr->destY, (char *)ptr->transp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_write("----------\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 calcDest(char dest, byte add) {
|
||||||
|
if (dest >= 0)
|
||||||
|
return dest + ((uint16)add << 7);
|
||||||
|
else
|
||||||
|
return dest - ((uint16)add << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void dbg_dumpFramePiece(Scen_AnimFramePiece* piece, int16 j, Scen_AnimLayer* layer) {
|
||||||
|
log_write("Piece for %d anim, %p: ", j, piece);
|
||||||
|
log_write("pictIndex = %x, pieceIndex = %d, destX = %d, destY = %d, not final = %d\n",
|
||||||
|
(uint16)piece->pictIndex,
|
||||||
|
(uint16)piece->pieceIndex,
|
||||||
|
layer->deltaX+calcDest(piece->destX, (char)((piece->pictIndex & 0xc0)>>6)),
|
||||||
|
layer->deltaY+calcDest(piece->destY, (char)((piece->pictIndex & 0x30)>>4)),
|
||||||
|
(int16)piece->notFinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbg_dumpAnimation(Scen_Animation* anim) {
|
||||||
|
int16 i, j;
|
||||||
|
Scen_AnimLayer* layer;
|
||||||
|
Scen_AnimFramePiece* piece;
|
||||||
|
|
||||||
|
log_write("dbg_dumpAnimation\n");
|
||||||
|
log_write("----------\n");
|
||||||
|
log_write("Layers count = %d\n", anim->layersCount);
|
||||||
|
|
||||||
|
for(i = 0; i < anim->layersCount; i++)
|
||||||
|
{
|
||||||
|
layer = anim->layers[i];
|
||||||
|
|
||||||
|
log_write("Layer %d:\n", i);
|
||||||
|
|
||||||
|
log_write("unknown0 = %d\n", layer->unknown0);
|
||||||
|
log_write("deltaX = %d\n", layer->deltaX);
|
||||||
|
log_write("deltaY = %d\n", layer->deltaY);
|
||||||
|
log_write("unknown1 = %d\n", layer->unknown1);
|
||||||
|
log_write("unknown2 = %d\n", layer->unknown2);
|
||||||
|
log_write("transparency = %d\n", (int16)layer->transp);
|
||||||
|
log_write("animsCount %d\n", layer->framesCount);
|
||||||
|
|
||||||
|
piece = layer->frames;
|
||||||
|
j = 0;
|
||||||
|
while(j < layer->framesCount)
|
||||||
|
{
|
||||||
|
dbg_dumpFramePiece(piece, j, layer);
|
||||||
|
if(piece->notFinal != 1)
|
||||||
|
j++;
|
||||||
|
piece++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_write("----------\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
27
gob/debug.h
Normal file
27
gob/debug.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __MY_DEBUG_H
|
||||||
|
#define __MY_DEBUG_H
|
||||||
|
|
||||||
|
#define LOG_NAME "log.txt"
|
||||||
|
|
||||||
|
#include "scenery.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void log_write(const char *format, ...);
|
||||||
|
|
||||||
|
void dbg_dumpMem(char *ptr, int16 size);
|
||||||
|
|
||||||
|
void dbg_dumpAnimation(Scen_Animation *anim);
|
||||||
|
void dbg_dumpFramePiece(Scen_AnimFramePiece *piece, int16 j,
|
||||||
|
Scen_AnimLayer *layer);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
908
gob/draw.cpp
Normal file
908
gob/draw.cpp
Normal file
|
@ -0,0 +1,908 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/draw.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/game.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/inter.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/palanim.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 draw_fontIndex = 0;
|
||||||
|
int16 draw_spriteLeft = 0;
|
||||||
|
int16 draw_spriteTop = 0;
|
||||||
|
int16 draw_spriteRight = 0;
|
||||||
|
int16 draw_spriteBottom = 0;
|
||||||
|
int16 draw_destSpriteX = 0;
|
||||||
|
int16 draw_destSpriteY = 0;
|
||||||
|
int16 draw_backColor = 0;
|
||||||
|
int16 draw_frontColor = 0;
|
||||||
|
char draw_letterToPrint = 0;
|
||||||
|
Draw_FontToSprite draw_fontToSprite[4];
|
||||||
|
int16 draw_destSurface = 0;
|
||||||
|
int16 draw_sourceSurface = 0;
|
||||||
|
int16 draw_renderFlags = 0;
|
||||||
|
int16 draw_backDeltaX = 0;
|
||||||
|
int16 draw_backDeltaY = 0;
|
||||||
|
FontDesc *draw_fonts[4];
|
||||||
|
char *draw_textToPrint = 0;
|
||||||
|
int16 draw_transparency = 0;
|
||||||
|
SurfaceDesc *draw_spritesArray[50];
|
||||||
|
|
||||||
|
int16 draw_invalidatedCount;
|
||||||
|
int16 draw_invalidatedTops[30];
|
||||||
|
int16 draw_invalidatedLefts[30];
|
||||||
|
int16 draw_invalidatedRights[30];
|
||||||
|
int16 draw_invalidatedBottoms[30];
|
||||||
|
|
||||||
|
char draw_noInvalidated = 0;
|
||||||
|
char draw_applyPal = 0;
|
||||||
|
char draw_paletteCleared = 0;
|
||||||
|
|
||||||
|
SurfaceDesc *draw_backSurface = 0;
|
||||||
|
SurfaceDesc *draw_frontSurface = 0;
|
||||||
|
|
||||||
|
int16 draw_unusedPalette1[18];
|
||||||
|
int16 draw_unusedPalette2[16];
|
||||||
|
Color draw_vgaPalette[256];
|
||||||
|
Color draw_vgaSmallPalette[16];
|
||||||
|
|
||||||
|
int16 draw_cursorX = 0;
|
||||||
|
int16 draw_cursorY = 0;
|
||||||
|
int16 draw_cursorWidth = 0;
|
||||||
|
int16 draw_cursorHeight = 0;
|
||||||
|
|
||||||
|
int16 draw_cursorXDeltaVar = -1;
|
||||||
|
int16 draw_cursorYDeltaVar = -1;
|
||||||
|
|
||||||
|
int16 draw_cursorIndex = 0;
|
||||||
|
int16 draw_transparentCursor = 0;
|
||||||
|
SurfaceDesc *draw_cursorSprites = 0;
|
||||||
|
SurfaceDesc *draw_cursorBack = 0;
|
||||||
|
int16 draw_cursorAnim = 0;
|
||||||
|
char draw_cursorAnimLow[40];
|
||||||
|
char draw_cursorAnimHigh[40];
|
||||||
|
char draw_cursorAnimDelays[40];
|
||||||
|
static uint32 draw_cursorTimeKey = 0;
|
||||||
|
|
||||||
|
int16 draw_palLoadData1[] = { 0, 17, 34, 51 };
|
||||||
|
int16 draw_palLoadData2[] = { 0, 68, 136, 204 };
|
||||||
|
|
||||||
|
void draw_invalidateRect(int16 left, int16 top, int16 right, int16 bottom) {
|
||||||
|
int16 temp;
|
||||||
|
int16 rect;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (draw_renderFlags & RENDERFLAG_NOINVALIDATE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (left > right) {
|
||||||
|
temp = left;
|
||||||
|
left = right;
|
||||||
|
right = temp;
|
||||||
|
}
|
||||||
|
if (top > bottom) {
|
||||||
|
temp = top;
|
||||||
|
top = bottom;
|
||||||
|
bottom = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left > 319 || right < 0 || top > 199 || bottom < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
draw_noInvalidated = 0;
|
||||||
|
|
||||||
|
if (draw_invalidatedCount >= 30) {
|
||||||
|
draw_invalidatedLefts[0] = 0;
|
||||||
|
draw_invalidatedTops[0] = 0;
|
||||||
|
draw_invalidatedRights[0] = 319;
|
||||||
|
draw_invalidatedBottoms[0] = 199;
|
||||||
|
draw_invalidatedCount = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left < 0)
|
||||||
|
left = 0;
|
||||||
|
|
||||||
|
if (right > 319)
|
||||||
|
right = 319;
|
||||||
|
|
||||||
|
if (top < 0)
|
||||||
|
top = 0;
|
||||||
|
|
||||||
|
if (bottom > 199)
|
||||||
|
bottom = 199;
|
||||||
|
|
||||||
|
left &= 0xfff0;
|
||||||
|
right |= 0x000f;
|
||||||
|
|
||||||
|
for (rect = 0; rect < draw_invalidatedCount; rect++) {
|
||||||
|
|
||||||
|
if (draw_invalidatedTops[rect] > top) {
|
||||||
|
if (draw_invalidatedTops[rect] > bottom) {
|
||||||
|
for (i = draw_invalidatedCount; i > rect; i--) {
|
||||||
|
draw_invalidatedLefts[i] =
|
||||||
|
draw_invalidatedLefts[i - 1];
|
||||||
|
draw_invalidatedTops[i] =
|
||||||
|
draw_invalidatedTops[i - 1];
|
||||||
|
draw_invalidatedRights[i] =
|
||||||
|
draw_invalidatedRights[i - 1];
|
||||||
|
draw_invalidatedBottoms[i] =
|
||||||
|
draw_invalidatedBottoms[i - 1];
|
||||||
|
}
|
||||||
|
draw_invalidatedLefts[rect] = left;
|
||||||
|
draw_invalidatedTops[rect] = top;
|
||||||
|
draw_invalidatedRights[rect] = right;
|
||||||
|
draw_invalidatedBottoms[rect] = bottom;
|
||||||
|
draw_invalidatedCount++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (draw_invalidatedBottoms[rect] < bottom)
|
||||||
|
draw_invalidatedBottoms[rect] = bottom;
|
||||||
|
|
||||||
|
if (draw_invalidatedLefts[rect] > left)
|
||||||
|
draw_invalidatedLefts[rect] = left;
|
||||||
|
|
||||||
|
if (draw_invalidatedRights[rect] < right)
|
||||||
|
draw_invalidatedRights[rect] = right;
|
||||||
|
|
||||||
|
draw_invalidatedTops[rect] = top;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_invalidatedBottoms[rect] < top)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (draw_invalidatedBottoms[rect] < bottom)
|
||||||
|
draw_invalidatedBottoms[rect] = bottom;
|
||||||
|
|
||||||
|
if (draw_invalidatedLefts[rect] > left)
|
||||||
|
draw_invalidatedLefts[rect] = left;
|
||||||
|
|
||||||
|
if (draw_invalidatedRights[rect] < right)
|
||||||
|
draw_invalidatedRights[rect] = right;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_invalidatedLefts[draw_invalidatedCount] = left;
|
||||||
|
draw_invalidatedTops[draw_invalidatedCount] = top;
|
||||||
|
draw_invalidatedRights[draw_invalidatedCount] = right;
|
||||||
|
draw_invalidatedBottoms[draw_invalidatedCount] = bottom;
|
||||||
|
draw_invalidatedCount++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_blitInvalidated(void) {
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (draw_cursorIndex == 4)
|
||||||
|
draw_blitCursor();
|
||||||
|
|
||||||
|
if (inter_terminate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (draw_noInvalidated && draw_applyPal == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (draw_noInvalidated) {
|
||||||
|
draw_setPalette();
|
||||||
|
draw_applyPal = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_applyPal) {
|
||||||
|
draw_clearPalette();
|
||||||
|
|
||||||
|
vid_drawSprite(draw_backSurface, draw_frontSurface, 0, 0, 319,
|
||||||
|
199, 0, 0, 0);
|
||||||
|
draw_setPalette();
|
||||||
|
draw_invalidatedCount = 0;
|
||||||
|
draw_noInvalidated = 1;
|
||||||
|
draw_applyPal = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doRangeClamp = 0;
|
||||||
|
for (i = 0; i < draw_invalidatedCount; i++) {
|
||||||
|
vid_drawSprite(draw_backSurface, draw_frontSurface,
|
||||||
|
draw_invalidatedLefts[i], draw_invalidatedTops[i],
|
||||||
|
draw_invalidatedRights[i], draw_invalidatedBottoms[i],
|
||||||
|
draw_invalidatedLefts[i], draw_invalidatedTops[i], 0);
|
||||||
|
}
|
||||||
|
doRangeClamp = 1;
|
||||||
|
|
||||||
|
draw_invalidatedCount = 0;
|
||||||
|
draw_noInvalidated = 1;
|
||||||
|
draw_applyPal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_setPalette(void) {
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
error("draw_setPalette: Video mode 0x%x is not supported!\n",
|
||||||
|
videoMode);
|
||||||
|
|
||||||
|
pPaletteDesc->unused1 = draw_unusedPalette1;
|
||||||
|
pPaletteDesc->unused2 = draw_unusedPalette2;
|
||||||
|
pPaletteDesc->vgaPal = draw_vgaPalette;
|
||||||
|
vid_setFullPalette(pPaletteDesc);
|
||||||
|
draw_paletteCleared = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_clearPalette(void) {
|
||||||
|
if (draw_paletteCleared == 0) {
|
||||||
|
draw_paletteCleared = 1;
|
||||||
|
util_clearPalette();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_blitCursor(void) {
|
||||||
|
if (draw_cursorIndex == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
draw_cursorIndex = -1;
|
||||||
|
if (draw_cursorX + draw_cursorWidth > 320)
|
||||||
|
draw_cursorWidth = 320 - draw_cursorX;
|
||||||
|
|
||||||
|
if (draw_cursorY + draw_cursorHeight > 200)
|
||||||
|
draw_cursorHeight = 200 - draw_cursorY;
|
||||||
|
|
||||||
|
if (draw_noInvalidated) {
|
||||||
|
vid_drawSprite(draw_backSurface, draw_frontSurface,
|
||||||
|
draw_cursorX, draw_cursorY,
|
||||||
|
draw_cursorX + draw_cursorWidth - 1,
|
||||||
|
draw_cursorY + draw_cursorHeight - 1, draw_cursorX,
|
||||||
|
draw_cursorY, 0);
|
||||||
|
} else {
|
||||||
|
draw_invalidateRect(draw_cursorX, draw_cursorY,
|
||||||
|
draw_cursorX + draw_cursorWidth - 1,
|
||||||
|
draw_cursorY + draw_cursorHeight - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_spriteOperation(int16 operation) {
|
||||||
|
uint16 id;
|
||||||
|
char *dataBuf;
|
||||||
|
Game_TotResItem *itemPtr;
|
||||||
|
int32 offset;
|
||||||
|
int16 len;
|
||||||
|
int16 i;
|
||||||
|
int16 x;
|
||||||
|
int16 y;
|
||||||
|
int16 perLine;
|
||||||
|
|
||||||
|
if (draw_sourceSurface >= 100)
|
||||||
|
draw_sourceSurface -= 80;
|
||||||
|
|
||||||
|
if (draw_destSurface >= 100)
|
||||||
|
draw_destSurface -= 80;
|
||||||
|
|
||||||
|
if (draw_renderFlags & RENDERFLAG_USEDELTAS) {
|
||||||
|
if (draw_sourceSurface == 21) {
|
||||||
|
draw_spriteLeft += draw_backDeltaX;
|
||||||
|
draw_spriteTop += draw_backDeltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_destSpriteX += draw_backDeltaX;
|
||||||
|
draw_destSpriteY += draw_backDeltaY;
|
||||||
|
if (operation == DRAW_DRAWLINE ||
|
||||||
|
(operation >= DRAW_DRAWBAR
|
||||||
|
&& operation <= DRAW_FILLRECTABS)) {
|
||||||
|
draw_spriteRight += draw_backDeltaX;
|
||||||
|
draw_spriteBottom += draw_backDeltaY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case DRAW_BLITSURF:
|
||||||
|
vid_drawSprite(draw_spritesArray[draw_sourceSurface],
|
||||||
|
draw_spritesArray[draw_destSurface],
|
||||||
|
draw_spriteLeft, draw_spriteTop,
|
||||||
|
draw_spriteLeft + draw_spriteRight - 1,
|
||||||
|
draw_spriteTop + draw_spriteBottom - 1,
|
||||||
|
draw_destSpriteX, draw_destSpriteY, draw_transparency);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX + draw_spriteRight - 1,
|
||||||
|
draw_destSpriteY + draw_spriteBottom - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_PUTPIXEL:
|
||||||
|
vid_putPixel(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_frontColor, draw_spritesArray[draw_destSurface]);
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX, draw_destSpriteY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_FILLRECT:
|
||||||
|
vid_fillRect(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX + draw_spriteRight - 1,
|
||||||
|
draw_destSpriteY + draw_spriteBottom - 1, draw_backColor);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX + draw_spriteRight - 1,
|
||||||
|
draw_destSpriteY + draw_spriteBottom - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_DRAWLINE:
|
||||||
|
vid_fillRect(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom, draw_frontColor);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_INVALIDATE:
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX - draw_spriteRight, draw_destSpriteY - draw_spriteBottom, // !!
|
||||||
|
draw_destSpriteX + draw_spriteRight,
|
||||||
|
draw_destSpriteY + draw_spriteBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_LOADSPRITE:
|
||||||
|
id = draw_spriteLeft;
|
||||||
|
if (id >= 30000) {
|
||||||
|
dataBuf =
|
||||||
|
game_loadExtData(id, &draw_spriteRight,
|
||||||
|
&draw_spriteBottom);
|
||||||
|
vid_drawPackedSprite((byte *)dataBuf, draw_spriteRight,
|
||||||
|
draw_spriteBottom, draw_destSpriteX,
|
||||||
|
draw_destSpriteY, draw_transparency,
|
||||||
|
draw_spritesArray[draw_destSurface]);
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX,
|
||||||
|
draw_destSpriteY,
|
||||||
|
draw_destSpriteX + draw_spriteRight - 1,
|
||||||
|
draw_destSpriteY + draw_spriteBottom - 1);
|
||||||
|
}
|
||||||
|
free(dataBuf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Load from .TOT resources
|
||||||
|
itemPtr = &game_totResourceTable->items[id];
|
||||||
|
offset = itemPtr->offset;
|
||||||
|
if (offset >= 0) {
|
||||||
|
dataBuf =
|
||||||
|
((char *)game_totResourceTable) +
|
||||||
|
szGame_TotResTable + szGame_TotResItem *
|
||||||
|
game_totResourceTable->itemsCount + offset;
|
||||||
|
} else {
|
||||||
|
dataBuf =
|
||||||
|
game_imFileData +
|
||||||
|
((int32 *)game_imFileData)[-offset - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_spriteRight = itemPtr->width;
|
||||||
|
draw_spriteBottom = itemPtr->height;
|
||||||
|
vid_drawPackedSprite((byte *)dataBuf,
|
||||||
|
draw_spriteRight, draw_spriteBottom,
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_transparency, draw_spritesArray[draw_destSurface]);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX + draw_spriteRight - 1,
|
||||||
|
draw_destSpriteY + draw_spriteBottom - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_PRINTTEXT:
|
||||||
|
len = strlen(draw_textToPrint);
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX +
|
||||||
|
len * draw_fonts[draw_fontIndex]->itemWidth - 1,
|
||||||
|
draw_destSpriteY +
|
||||||
|
draw_fonts[draw_fontIndex]->itemHeight - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
vid_drawLetter(draw_textToPrint[i],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_fonts[draw_fontIndex],
|
||||||
|
draw_transparency,
|
||||||
|
draw_frontColor, draw_backColor,
|
||||||
|
draw_spritesArray[draw_destSurface]);
|
||||||
|
|
||||||
|
draw_destSpriteX += draw_fonts[draw_fontIndex]->itemWidth;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_DRAWBAR:
|
||||||
|
vid_drawLine(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_spriteBottom,
|
||||||
|
draw_spriteRight, draw_spriteBottom, draw_frontColor);
|
||||||
|
|
||||||
|
vid_drawLine(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX, draw_spriteBottom, draw_frontColor);
|
||||||
|
|
||||||
|
vid_drawLine(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_spriteRight, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom, draw_frontColor);
|
||||||
|
|
||||||
|
vid_drawLine(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_destSpriteY, draw_frontColor);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_CLEARRECT:
|
||||||
|
if (draw_backColor < 16) {
|
||||||
|
vid_fillRect(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom,
|
||||||
|
draw_backColor);
|
||||||
|
}
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_FILLRECTABS:
|
||||||
|
vid_fillRect(draw_spritesArray[draw_destSurface],
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom, draw_backColor);
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRAW_DRAWLETTER:
|
||||||
|
if (draw_fontToSprite[draw_fontIndex].sprite == -1) {
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX,
|
||||||
|
draw_destSpriteY,
|
||||||
|
draw_destSpriteX +
|
||||||
|
draw_fonts[draw_fontIndex]->itemWidth - 1,
|
||||||
|
draw_destSpriteY +
|
||||||
|
draw_fonts[draw_fontIndex]->itemHeight -
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
vid_drawLetter(draw_letterToPrint,
|
||||||
|
draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_fonts[draw_fontIndex],
|
||||||
|
draw_transparency,
|
||||||
|
draw_frontColor, draw_backColor,
|
||||||
|
draw_spritesArray[draw_destSurface]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
perLine =
|
||||||
|
draw_spritesArray[(int16)draw_fontToSprite[draw_fontIndex].
|
||||||
|
sprite]->width / draw_fontToSprite[draw_fontIndex].width;
|
||||||
|
|
||||||
|
y = (draw_letterToPrint -
|
||||||
|
draw_fontToSprite[draw_fontIndex].base) / perLine *
|
||||||
|
draw_fontToSprite[draw_fontIndex].height;
|
||||||
|
|
||||||
|
x = (draw_letterToPrint -
|
||||||
|
draw_fontToSprite[draw_fontIndex].base) % perLine *
|
||||||
|
draw_fontToSprite[draw_fontIndex].width;
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_invalidateRect(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_destSpriteX +
|
||||||
|
draw_fontToSprite[draw_fontIndex].width,
|
||||||
|
draw_destSpriteY +
|
||||||
|
draw_fontToSprite[draw_fontIndex].height);
|
||||||
|
}
|
||||||
|
|
||||||
|
vid_drawSprite(draw_spritesArray[(int16)draw_fontToSprite
|
||||||
|
[draw_fontIndex].sprite],
|
||||||
|
draw_spritesArray[draw_destSurface], x, y,
|
||||||
|
x + draw_fontToSprite[draw_fontIndex].width,
|
||||||
|
y + draw_fontToSprite[draw_fontIndex].height,
|
||||||
|
draw_destSpriteX, draw_destSpriteY, draw_transparency);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_renderFlags & RENDERFLAG_USEDELTAS) {
|
||||||
|
if (draw_sourceSurface == 21) {
|
||||||
|
draw_spriteLeft -= draw_backDeltaX;
|
||||||
|
draw_spriteTop -= draw_backDeltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_destSurface == 21) {
|
||||||
|
draw_destSpriteX -= draw_backDeltaX;
|
||||||
|
draw_destSpriteY -= draw_backDeltaY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_animateCursor(int16 cursor) {
|
||||||
|
int16 newX = 0;
|
||||||
|
int16 newY = 0;
|
||||||
|
Game_Collision *ptr;
|
||||||
|
int16 minX;
|
||||||
|
int16 minY;
|
||||||
|
int16 maxX;
|
||||||
|
int16 maxY;
|
||||||
|
int16 cursorIndex;
|
||||||
|
|
||||||
|
cursorIndex = cursor;
|
||||||
|
|
||||||
|
if (cursorIndex == -1) {
|
||||||
|
cursorIndex = 0;
|
||||||
|
for (ptr = game_collisionAreas; ptr->left != -1; ptr++) {
|
||||||
|
if (ptr->flags & 0xfff0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptr->left > inter_mouseX)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptr->right < inter_mouseX)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptr->top > inter_mouseY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptr->bottom < inter_mouseY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((ptr->flags & 0xf) < 3)
|
||||||
|
cursorIndex = 1;
|
||||||
|
else
|
||||||
|
cursorIndex = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (draw_cursorAnimLow[cursorIndex] == -1)
|
||||||
|
cursorIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_cursorAnimLow[cursorIndex] != -1) {
|
||||||
|
if (cursorIndex == draw_cursorIndex) {
|
||||||
|
if (draw_cursorAnimDelays[draw_cursorIndex] != 0 &&
|
||||||
|
draw_cursorAnimDelays[draw_cursorIndex] * 10 +
|
||||||
|
draw_cursorTimeKey <= util_getTimeKey()) {
|
||||||
|
draw_cursorAnim++;
|
||||||
|
draw_cursorTimeKey = util_getTimeKey();
|
||||||
|
} else {
|
||||||
|
/* if(draw_noInvalidated &&
|
||||||
|
inter_mouseX == draw_cursorX && inter_mouseY == draw_cursorY)
|
||||||
|
return;*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
draw_cursorIndex = cursorIndex;
|
||||||
|
if (draw_cursorAnimDelays[draw_cursorIndex] != 0) {
|
||||||
|
draw_cursorAnim =
|
||||||
|
draw_cursorAnimLow[draw_cursorIndex];
|
||||||
|
draw_cursorTimeKey = util_getTimeKey();
|
||||||
|
} else {
|
||||||
|
draw_cursorAnim = draw_cursorIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_cursorAnimDelays[draw_cursorIndex] != 0 &&
|
||||||
|
(draw_cursorAnimHigh[draw_cursorIndex] < draw_cursorAnim ||
|
||||||
|
draw_cursorAnimLow[draw_cursorIndex] >
|
||||||
|
draw_cursorAnim)) {
|
||||||
|
draw_cursorAnim = draw_cursorAnimLow[draw_cursorIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
newX = inter_mouseX;
|
||||||
|
newY = inter_mouseY;
|
||||||
|
if (draw_cursorXDeltaVar != -1) {
|
||||||
|
newX -= READ_LE_UINT16(inter_variables + draw_cursorIndex * 4 +
|
||||||
|
(draw_cursorXDeltaVar / 4) * 4);
|
||||||
|
newY -= READ_LE_UINT16(inter_variables + draw_cursorIndex * 4 +
|
||||||
|
(draw_cursorYDeltaVar / 4) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
minX = MIN(newX, draw_cursorX);
|
||||||
|
minY = MIN(newY, draw_cursorY);
|
||||||
|
maxX = MAX(draw_cursorX, newX) + draw_cursorWidth - 1;
|
||||||
|
maxY = MAX(draw_cursorY, newY) + draw_cursorHeight - 1;
|
||||||
|
vid_drawSprite(draw_backSurface, draw_cursorBack,
|
||||||
|
newX, newY, newX + draw_cursorWidth - 1,
|
||||||
|
newY + draw_cursorHeight - 1, 0, 0, 0);
|
||||||
|
|
||||||
|
vid_drawSprite(draw_cursorSprites, draw_backSurface,
|
||||||
|
draw_cursorWidth * draw_cursorAnim, 0,
|
||||||
|
draw_cursorWidth * (draw_cursorAnim + 1) - 1,
|
||||||
|
draw_cursorHeight - 1, newX, newY, draw_transparentCursor);
|
||||||
|
|
||||||
|
if (draw_noInvalidated == 0) {
|
||||||
|
cursorIndex = draw_cursorIndex;
|
||||||
|
draw_cursorIndex = -1;
|
||||||
|
draw_blitInvalidated();
|
||||||
|
draw_cursorIndex = cursorIndex;
|
||||||
|
} else {
|
||||||
|
vid_waitRetrace(videoMode);
|
||||||
|
if (minY < 50)
|
||||||
|
util_delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
vid_drawSprite(draw_backSurface, draw_frontSurface,
|
||||||
|
minX, minY, maxX, maxY, minX, minY, 0);
|
||||||
|
|
||||||
|
vid_drawSprite(draw_cursorBack, draw_backSurface,
|
||||||
|
0, 0, draw_cursorWidth - 1, draw_cursorHeight - 1,
|
||||||
|
newX, newY, 0);
|
||||||
|
} else {
|
||||||
|
draw_blitCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_cursorX = newX;
|
||||||
|
draw_cursorY = newY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_interPalLoad(void) {
|
||||||
|
int16 i;
|
||||||
|
int16 ind1;
|
||||||
|
int16 ind2;
|
||||||
|
byte cmd;
|
||||||
|
char *palPtr;
|
||||||
|
|
||||||
|
cmd = *inter_execPtr++;
|
||||||
|
draw_applyPal = 0;
|
||||||
|
if (cmd & 0x80)
|
||||||
|
cmd &= 0x7f;
|
||||||
|
else
|
||||||
|
draw_applyPal = 1;
|
||||||
|
|
||||||
|
if (cmd == 49) {
|
||||||
|
warning("inter_palLoad: cmd == 49 is not supported");
|
||||||
|
//var_B = 1;
|
||||||
|
for (i = 0; i < 18; i++, inter_execPtr++) {
|
||||||
|
if (i < 2) {
|
||||||
|
if (draw_applyPal == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
draw_unusedPalette1[i] = *inter_execPtr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//if(*inter_execPtr != 0)
|
||||||
|
// var_B = 0;
|
||||||
|
|
||||||
|
ind1 = *inter_execPtr >> 4;
|
||||||
|
ind2 = (*inter_execPtr & 0xf);
|
||||||
|
|
||||||
|
draw_unusedPalette1[i] =
|
||||||
|
((draw_palLoadData1[ind1] + draw_palLoadData2[ind2]) << 8) +
|
||||||
|
(draw_palLoadData2[ind1] + draw_palLoadData1[ind2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pPaletteDesc->unused1 = draw_unusedPalette1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case 52:
|
||||||
|
for (i = 0; i < 16; i++, inter_execPtr += 3) {
|
||||||
|
draw_vgaSmallPalette[i].red = inter_execPtr[0];
|
||||||
|
draw_vgaSmallPalette[i].green = inter_execPtr[1];
|
||||||
|
draw_vgaSmallPalette[i].blue = inter_execPtr[2];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 50:
|
||||||
|
for (i = 0; i < 16; i++, inter_execPtr++)
|
||||||
|
draw_unusedPalette2[i] = *inter_execPtr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 53:
|
||||||
|
palPtr = game_loadTotResource(inter_load16());
|
||||||
|
memcpy((char *)draw_vgaPalette, palPtr, 768);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 54:
|
||||||
|
memset((char *)draw_vgaPalette, 0, 768);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!draw_applyPal) {
|
||||||
|
pPaletteDesc->unused2 = draw_unusedPalette2;
|
||||||
|
pPaletteDesc->unused1 = draw_unusedPalette1;
|
||||||
|
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
pPaletteDesc->vgaPal = (Color *)draw_vgaSmallPalette;
|
||||||
|
else
|
||||||
|
pPaletteDesc->vgaPal = (Color *)draw_vgaPalette;
|
||||||
|
|
||||||
|
pal_fade((PalDesc *) pPaletteDesc, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_printText(void) {
|
||||||
|
int16 savedFlags;
|
||||||
|
int16 destSpriteX;
|
||||||
|
char *dataPtr;
|
||||||
|
char *ptr;
|
||||||
|
char *ptr2;
|
||||||
|
int16 index;
|
||||||
|
int16 destX;
|
||||||
|
int16 destY;
|
||||||
|
char cmd;
|
||||||
|
int16 val;
|
||||||
|
char buf[20];
|
||||||
|
|
||||||
|
index = inter_load16();
|
||||||
|
dataPtr = (char *)game_totTextData + game_totTextData->items[index].offset;
|
||||||
|
ptr = dataPtr;
|
||||||
|
|
||||||
|
if (draw_renderFlags & RENDERFLAG_CAPTUREPUSH) {
|
||||||
|
draw_destSpriteX = READ_LE_UINT16(ptr);
|
||||||
|
draw_destSpriteY = READ_LE_UINT16(ptr + 2);
|
||||||
|
draw_spriteRight = READ_LE_UINT16(ptr + 4) - draw_destSpriteX + 1;
|
||||||
|
draw_spriteBottom = READ_LE_UINT16(ptr + 6) - draw_destSpriteY + 1;
|
||||||
|
game_capturePush(draw_destSpriteX, draw_destSpriteY,
|
||||||
|
draw_spriteRight, draw_spriteBottom);
|
||||||
|
(*scen_pCaptureCounter)++;
|
||||||
|
}
|
||||||
|
draw_destSpriteX = READ_LE_UINT16(ptr);
|
||||||
|
destX = draw_destSpriteX;
|
||||||
|
|
||||||
|
draw_destSpriteY = READ_LE_UINT16(ptr + 2);
|
||||||
|
destY = draw_destSpriteY;
|
||||||
|
|
||||||
|
draw_spriteRight = READ_LE_UINT16(ptr + 4);
|
||||||
|
draw_spriteBottom = READ_LE_UINT16(ptr + 6);
|
||||||
|
draw_destSurface = 21;
|
||||||
|
|
||||||
|
ptr += 8;
|
||||||
|
|
||||||
|
draw_backColor = *ptr++;
|
||||||
|
draw_transparency = 1;
|
||||||
|
draw_spriteOperation(DRAW_CLEARRECT);
|
||||||
|
|
||||||
|
draw_backColor = 0;
|
||||||
|
savedFlags = draw_renderFlags;
|
||||||
|
|
||||||
|
draw_renderFlags &= ~RENDERFLAG_NOINVALIDATE;
|
||||||
|
for (; (draw_destSpriteX = READ_LE_UINT16(ptr)) != -1; ptr++) {
|
||||||
|
draw_destSpriteX += destX;
|
||||||
|
draw_destSpriteY = READ_LE_UINT16(ptr + 2) + destY;
|
||||||
|
draw_spriteRight = READ_LE_UINT16(ptr + 4) + destX;
|
||||||
|
draw_spriteBottom = READ_LE_UINT16(ptr + 6) + destY;
|
||||||
|
ptr += 8;
|
||||||
|
|
||||||
|
cmd = (*ptr & 0xf0) >> 4;
|
||||||
|
if (cmd == 0) {
|
||||||
|
draw_frontColor = *ptr & 0xf;
|
||||||
|
draw_spriteOperation(DRAW_DRAWLINE);
|
||||||
|
} else if (cmd == 1) {
|
||||||
|
draw_frontColor = *ptr & 0xf;
|
||||||
|
draw_spriteOperation(DRAW_DRAWBAR);
|
||||||
|
} else if (cmd == 2) {
|
||||||
|
draw_backColor = *ptr & 0xf;
|
||||||
|
draw_spriteOperation(DRAW_FILLRECTABS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
|
for (ptr2 = ptr; *ptr2 != 1; ptr2++) {
|
||||||
|
if (*ptr2 == 3)
|
||||||
|
ptr2++;
|
||||||
|
|
||||||
|
if (*ptr2 == 2)
|
||||||
|
ptr2 += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr2++;
|
||||||
|
|
||||||
|
while (*ptr != 1) {
|
||||||
|
cmd = *ptr;
|
||||||
|
if (cmd == 3) {
|
||||||
|
ptr++;
|
||||||
|
draw_fontIndex = (*ptr & 0xf0) >> 4;
|
||||||
|
draw_frontColor = *ptr & 0xf;
|
||||||
|
ptr++;
|
||||||
|
continue;
|
||||||
|
} else if (cmd == 2) {
|
||||||
|
ptr++;
|
||||||
|
draw_destSpriteX = destX + READ_LE_UINT16(ptr);
|
||||||
|
draw_destSpriteY = destY + READ_LE_UINT16(ptr + 2);
|
||||||
|
ptr += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((byte)*ptr != 0xba) {
|
||||||
|
draw_letterToPrint = *ptr;
|
||||||
|
draw_spriteOperation(DRAW_DRAWLETTER);
|
||||||
|
draw_destSpriteX +=
|
||||||
|
draw_fonts[draw_fontIndex]->itemWidth;
|
||||||
|
ptr++;
|
||||||
|
} else {
|
||||||
|
cmd = ptr2[17] & 0x7f;
|
||||||
|
if (cmd == 0) {
|
||||||
|
val = READ_LE_UINT16(ptr2 + 18) * 4;
|
||||||
|
sprintf(buf, "%ld", READ_LE_UINT32(inter_variables + val));
|
||||||
|
} else if (cmd == 1) {
|
||||||
|
val = READ_LE_UINT16(ptr2 + 18) * 4;
|
||||||
|
|
||||||
|
strcpy(buf, inter_variables + val);
|
||||||
|
} else {
|
||||||
|
val = READ_LE_UINT16(ptr2 + 18) * 4;
|
||||||
|
|
||||||
|
sprintf(buf, "%ld", READ_LE_UINT32(inter_variables + val));
|
||||||
|
if (buf[0] == '-') {
|
||||||
|
while (strlen(buf) - 1 < (uint32)ptr2[17]) {
|
||||||
|
util_insertStr((char *)"0", buf, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (strlen(buf) - 1 < (uint32)ptr2[17]) {
|
||||||
|
util_insertStr((char *)"0", buf, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
util_insertStr((char *)",", buf, strlen(buf) + 1 - ptr2[17]);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_textToPrint = buf;
|
||||||
|
destSpriteX = draw_destSpriteX;
|
||||||
|
draw_spriteOperation(DRAW_PRINTTEXT);
|
||||||
|
if (ptr2[17] & 0x80) {
|
||||||
|
if (ptr[1] == ' ') {
|
||||||
|
draw_destSpriteX += draw_fonts[draw_fontIndex]->itemWidth;
|
||||||
|
while (ptr[1] == ' ')
|
||||||
|
ptr++;
|
||||||
|
if (ptr[1] == 2) {
|
||||||
|
if (READ_LE_UINT16(ptr + 4) == draw_destSpriteY)
|
||||||
|
ptr += 5;
|
||||||
|
}
|
||||||
|
} else if (ptr[1] == 2 && READ_LE_UINT16(ptr + 4) == draw_destSpriteY) {
|
||||||
|
ptr += 5;
|
||||||
|
draw_destSpriteX += draw_fonts[draw_fontIndex]->itemWidth;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
draw_destSpriteX = destSpriteX + draw_fonts[draw_fontIndex]->itemWidth;
|
||||||
|
}
|
||||||
|
ptr2 += 23;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_renderFlags = savedFlags;
|
||||||
|
if (draw_renderFlags & 4) {
|
||||||
|
warning("draw_printText: Input not supported!");
|
||||||
|
// xor ax, ax
|
||||||
|
// loc_436_1391:
|
||||||
|
// xor dx, dx
|
||||||
|
// push ax
|
||||||
|
// push dx
|
||||||
|
// push ax
|
||||||
|
// push dx
|
||||||
|
// push ax
|
||||||
|
// mov al, 0
|
||||||
|
// push ax
|
||||||
|
// call sub_9FF_1E71
|
||||||
|
// add sp, 0Ch
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((draw_renderFlags & RENDERFLAG_CAPTUREPOP) && *scen_pCaptureCounter != 0) {
|
||||||
|
(*scen_pCaptureCounter)--;
|
||||||
|
game_capturePop(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
111
gob/draw.h
Normal file
111
gob/draw.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __DRAW_H
|
||||||
|
#define __DRAW_H
|
||||||
|
|
||||||
|
#include "gob/video.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#define RENDERFLAG_NOINVALIDATE 1
|
||||||
|
#define RENDERFLAG_CAPTUREPUSH 2
|
||||||
|
#define RENDERFLAG_CAPTUREPOP 8
|
||||||
|
#define RENDERFLAG_USEDELTAS 0x10
|
||||||
|
|
||||||
|
typedef struct Draw_FontToSprite {
|
||||||
|
char sprite;
|
||||||
|
char base;
|
||||||
|
char width;
|
||||||
|
char height;
|
||||||
|
} Draw_FontToSprite;
|
||||||
|
|
||||||
|
extern int16 draw_fontIndex;
|
||||||
|
extern int16 draw_spriteLeft;
|
||||||
|
extern int16 draw_spriteTop;
|
||||||
|
extern int16 draw_spriteRight;
|
||||||
|
extern int16 draw_spriteBottom;
|
||||||
|
extern int16 draw_destSpriteX;
|
||||||
|
extern int16 draw_destSpriteY;
|
||||||
|
extern int16 draw_backColor;
|
||||||
|
extern int16 draw_frontColor;
|
||||||
|
extern char draw_letterToPrint;
|
||||||
|
extern Draw_FontToSprite draw_fontToSprite[4];
|
||||||
|
extern int16 draw_destSurface;
|
||||||
|
extern int16 draw_sourceSurface;
|
||||||
|
extern int16 draw_renderFlags;
|
||||||
|
extern int16 draw_backDeltaX;
|
||||||
|
extern int16 draw_backDeltaY;
|
||||||
|
extern FontDesc *draw_fonts[4];
|
||||||
|
extern char *draw_textToPrint;
|
||||||
|
extern int16 draw_transparency;
|
||||||
|
extern SurfaceDesc *draw_spritesArray[50];
|
||||||
|
|
||||||
|
extern int16 draw_invalidatedCount;
|
||||||
|
extern int16 draw_invalidatedTops[30];
|
||||||
|
extern int16 draw_invalidatedLefts[30];
|
||||||
|
extern int16 draw_invalidatedRights[30];
|
||||||
|
extern int16 draw_invalidatedBottoms[30];
|
||||||
|
|
||||||
|
extern char draw_noInvalidated;
|
||||||
|
extern char draw_doFullFlip;
|
||||||
|
extern char draw_paletteCleared;
|
||||||
|
|
||||||
|
extern int16 draw_cursorIndex;
|
||||||
|
extern int16 draw_transparentCursor;
|
||||||
|
|
||||||
|
extern SurfaceDesc *draw_backSurface;
|
||||||
|
extern SurfaceDesc *draw_frontSurface;
|
||||||
|
|
||||||
|
extern int16 draw_unusedPalette1[18];
|
||||||
|
extern int16 draw_unusedPalette2[16];
|
||||||
|
extern Color draw_vgaPalette[256];
|
||||||
|
extern Color draw_vgaSmallPalette[16];
|
||||||
|
|
||||||
|
extern int16 draw_cursorX;
|
||||||
|
extern int16 draw_cursorY;
|
||||||
|
extern int16 draw_cursorWidth;
|
||||||
|
extern int16 draw_cursorHeight;
|
||||||
|
|
||||||
|
extern int16 draw_cursorXDeltaVar;
|
||||||
|
extern int16 draw_cursorYDeltaVar;
|
||||||
|
|
||||||
|
extern SurfaceDesc *draw_cursorSprites;
|
||||||
|
extern SurfaceDesc *draw_cursorBack;
|
||||||
|
extern int16 draw_cursorAnim;
|
||||||
|
extern char draw_cursorAnimLow[40];
|
||||||
|
extern char draw_cursorAnimHigh[40];
|
||||||
|
extern char draw_cursorAnimDelays[40];
|
||||||
|
extern char draw_applyPal;
|
||||||
|
|
||||||
|
void draw_invalidateRect(int16 left, int16 top, int16 right, int16 bottom);
|
||||||
|
void draw_blitInvalidated(void);
|
||||||
|
void draw_setPalette(void);
|
||||||
|
void draw_clearPalette(void);
|
||||||
|
void draw_blitCursor(void);
|
||||||
|
|
||||||
|
void draw_spriteOperation(int16 operation);
|
||||||
|
void draw_animateCursor(int16 cursor);
|
||||||
|
void draw_interPalLoad(void);
|
||||||
|
void draw_printText(void);
|
||||||
|
// Draw operations
|
||||||
|
|
||||||
|
#define DRAW_BLITSURF 0
|
||||||
|
#define DRAW_PUTPIXEL 1
|
||||||
|
#define DRAW_FILLRECT 2
|
||||||
|
#define DRAW_DRAWLINE 3
|
||||||
|
#define DRAW_INVALIDATE 4
|
||||||
|
#define DRAW_LOADSPRITE 5
|
||||||
|
#define DRAW_PRINTTEXT 6
|
||||||
|
#define DRAW_DRAWBAR 7
|
||||||
|
#define DRAW_CLEARRECT 8
|
||||||
|
#define DRAW_FILLRECTABS 9
|
||||||
|
#define DRAW_DRAWLETTER 10
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __DRAW_H */
|
59
gob/driver_vga.cpp
Normal file
59
gob/driver_vga.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "driver_vga.h"
|
||||||
|
|
||||||
|
#define STUB_FUNC printf("STUB: %s\n", __PRETTY_FUNCTION__)
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
|
||||||
|
if (x >= 0 && x < dest->width && y >= 0 && y < dest->height) {
|
||||||
|
int16 width = (right - left) + 1;
|
||||||
|
int16 height = (bottom - top) + 1;
|
||||||
|
|
||||||
|
byte *srcPos = source->vidPtr + (top * source->width) + left;
|
||||||
|
byte *destPos = dest->vidPtr + (y * dest->width) + x;
|
||||||
|
while (height--) {
|
||||||
|
for (int16 i = 0; i < width; ++i) {
|
||||||
|
if (srcPos[i])
|
||||||
|
destPos[i] = srcPos[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
srcPos += source->width; //width ?
|
||||||
|
destPos += dest->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGAVideoDriver::fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) {
|
||||||
|
if (left < dest->width && right < dest->width && top < dest->height && bottom < dest->height) {
|
||||||
|
byte *pos = dest->vidPtr + (top * dest->width) + left;
|
||||||
|
int16 width = (right - left) + 1;
|
||||||
|
int16 height = (bottom - top) + 1;
|
||||||
|
while (height--) {
|
||||||
|
for (int16 i = 0; i < width; ++i) {
|
||||||
|
pos[i] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += dest->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) {
|
||||||
|
if (x >= 0 && x < dest->width && y >= 0 && y < dest->height)
|
||||||
|
dest->vidPtr[(y * dest->width) + x] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGAVideoDriver::drawLetter(char item, int16 x, int16 y, FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc *dest) {
|
||||||
|
STUB_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGAVideoDriver::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) {
|
||||||
|
STUB_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc *dest) {
|
||||||
|
STUB_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
22
gob/driver_vga.h
Normal file
22
gob/driver_vga.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef DRIVER_VGA
|
||||||
|
#define DRIVER_VGA
|
||||||
|
|
||||||
|
#include "video.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
class VGAVideoDriver : public VideoDriver {
|
||||||
|
public:
|
||||||
|
VGAVideoDriver() {}
|
||||||
|
virtual ~VGAVideoDriver() {}
|
||||||
|
void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp);
|
||||||
|
void fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color);
|
||||||
|
void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest);
|
||||||
|
void drawLetter(char item, int16 x, int16 y, FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc *dest);
|
||||||
|
void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color);
|
||||||
|
void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc *dest);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1909
gob/game.cpp
Normal file
1909
gob/game.cpp
Normal file
File diff suppressed because it is too large
Load diff
151
gob/game.h
Normal file
151
gob/game.h
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __GAME_H
|
||||||
|
#define __GAME_H
|
||||||
|
|
||||||
|
#include "gob/sound.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#pragma START_PACK_STRUCTS
|
||||||
|
#define szGame_ExtItem (4 + 2 + 2 + 2)
|
||||||
|
typedef struct Game_ExtItem {
|
||||||
|
int32 offset; // offset from the table end
|
||||||
|
uint16 size;
|
||||||
|
int16 width; // width&0x7fff - width, width&0x8000 - pack flag
|
||||||
|
int16 height; // not zero
|
||||||
|
} GCC_PACK Game_ExtItem;
|
||||||
|
|
||||||
|
#define szGame_ExtTable (2 + 1)
|
||||||
|
typedef struct Game_ExtTable {
|
||||||
|
int16 itemsCount;
|
||||||
|
byte unknown;
|
||||||
|
Game_ExtItem items[1];
|
||||||
|
} GCC_PACK Game_ExtTable;
|
||||||
|
|
||||||
|
#define szGame_TotResItem (4 + 2 + 2 + 2)
|
||||||
|
typedef struct Game_TotResItem {
|
||||||
|
int32 offset; // if > 0, then offset from end of resource table.
|
||||||
|
// If < 0, then -offset-1 is index in .IM file table
|
||||||
|
int16 size;
|
||||||
|
int16 width;
|
||||||
|
int16 height;
|
||||||
|
} GCC_PACK Game_TotResItem;
|
||||||
|
|
||||||
|
#define szGame_TotResTable (2 + 1)
|
||||||
|
typedef struct Game_TotResTable {
|
||||||
|
int16 itemsCount;
|
||||||
|
byte unknown;
|
||||||
|
Game_TotResItem items[1];
|
||||||
|
} GCC_PACK Game_TotResTable;
|
||||||
|
|
||||||
|
#define szGame_TotTextItem (2 + 2)
|
||||||
|
typedef struct Game_TotTextItem {
|
||||||
|
int16 offset;
|
||||||
|
int16 size;
|
||||||
|
} GCC_PACK Game_TotTextItem;
|
||||||
|
|
||||||
|
#define szGame_TotTextTable (2)
|
||||||
|
typedef struct Game_TotTextTable {
|
||||||
|
int16 itemsCount;
|
||||||
|
Game_TotTextItem items[1];
|
||||||
|
} GCC_PACK Game_TotTextTable;
|
||||||
|
|
||||||
|
typedef struct Game_Collision {
|
||||||
|
int16 id;
|
||||||
|
int16 left;
|
||||||
|
int16 top;
|
||||||
|
int16 right;
|
||||||
|
int16 bottom;
|
||||||
|
int16 flags;
|
||||||
|
int16 key;
|
||||||
|
int16 funcEnter;
|
||||||
|
int16 funcLeave;
|
||||||
|
} GCC_PACK Game_Collision;
|
||||||
|
|
||||||
|
typedef struct Game_InputDesc {
|
||||||
|
int16 fontIndex;
|
||||||
|
int16 backColor;
|
||||||
|
int16 frontColor;
|
||||||
|
char *ptr;
|
||||||
|
} GCC_PACK Game_InputDesc;
|
||||||
|
#pragma END_PACK_STRUCTS
|
||||||
|
|
||||||
|
extern Game_Collision *game_collisionAreas;
|
||||||
|
|
||||||
|
extern int16 game_lastCollKey;
|
||||||
|
extern int16 game_lastCollAreaIndex;
|
||||||
|
extern int16 game_lastCollId;
|
||||||
|
|
||||||
|
extern int16 game_activeCollResId;
|
||||||
|
extern int16 game_activeCollIndex;
|
||||||
|
extern char game_handleMouse;
|
||||||
|
extern char game_forceHandleMouse;
|
||||||
|
|
||||||
|
extern char game_tempStr[256];
|
||||||
|
|
||||||
|
extern Game_ExtTable *game_extTable;
|
||||||
|
extern char *game_totFileData;
|
||||||
|
extern Game_TotTextTable *game_totTextData;
|
||||||
|
extern Game_TotResTable *game_totResourceTable;
|
||||||
|
extern char *game_imFileData;
|
||||||
|
extern int16 game_extHandle;
|
||||||
|
extern char game_curExtFile[14];
|
||||||
|
extern char game_curTotFile[14];
|
||||||
|
extern char game_curImaFile[18];
|
||||||
|
|
||||||
|
extern int16 game_collStackSize;
|
||||||
|
extern Game_Collision *game_collStack[3];
|
||||||
|
extern int16 game_collStackElemSizes[3];
|
||||||
|
|
||||||
|
extern int16 game_mouseButtons;
|
||||||
|
|
||||||
|
extern Snd_SoundDesc *game_soundSamples[20];
|
||||||
|
|
||||||
|
extern char game_soundFromExt[20];
|
||||||
|
extern char game_totToLoad[20];
|
||||||
|
|
||||||
|
extern int32 game_startTimeKey;
|
||||||
|
extern char game_shouldPushColls;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
char *game_loadExtData(int16 dataId, int16 *pResWidth, int16 *pResHeight);
|
||||||
|
void game_clearCollisions(void);
|
||||||
|
void game_addNewCollision(int16 val_0, int16 left, int16 top, int16 right, int16 bottom,
|
||||||
|
int16 flags, int16 key, int16 val_E, int16 val_10);
|
||||||
|
void game_freeCollision(int16 id);
|
||||||
|
char *game_loadTotResource(int16 id);
|
||||||
|
void game_capturePush(int16 left, int16 top, int16 width, int16 height);
|
||||||
|
|
||||||
|
void game_capturePush(int16 left, int16 top, int16 width, int16 height);
|
||||||
|
void game_capturePop(char doDraw);
|
||||||
|
|
||||||
|
void game_loadSound(int16 slot, char *dataPtr);
|
||||||
|
void game_interLoadSound(int16 slot);
|
||||||
|
void game_freeSoundSlot(int16 slot);
|
||||||
|
int16 game_checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
|
||||||
|
char handleMouse);
|
||||||
|
int16 game_checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
|
||||||
|
int16 *pResIndex);
|
||||||
|
int16 game_inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor,
|
||||||
|
int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime);
|
||||||
|
int16 game_multiEdit(int16 time, int16 index, int16 *pCurPos,
|
||||||
|
Game_InputDesc * inpDesc);
|
||||||
|
int16 game_adjustKey(int16 key);
|
||||||
|
void game_collisionsBlock(void);
|
||||||
|
void game_prepareStart(void);
|
||||||
|
void game_loadTotFile(char *path);
|
||||||
|
void game_loadExtTable(void);
|
||||||
|
void game_loadImFile(void);
|
||||||
|
void game_playTot(int16 skipPlay);
|
||||||
|
void game_start(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
175
gob/global.cpp
Normal file
175
gob/global.cpp
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
char pressedKeys[128];
|
||||||
|
|
||||||
|
char useMouse = UNDEF;
|
||||||
|
int16 mousePresent = UNDEF;
|
||||||
|
|
||||||
|
int16 presentCGA = UNDEF;
|
||||||
|
int16 presentEGA = UNDEF;
|
||||||
|
int16 presentVGA = UNDEF;
|
||||||
|
int16 presentHER = UNDEF;
|
||||||
|
|
||||||
|
int16 videoMode = 0;
|
||||||
|
|
||||||
|
int16 disableVideoCfg;
|
||||||
|
|
||||||
|
/* Sound */
|
||||||
|
uint16 presentSound = 0x8000; /* undefined values */
|
||||||
|
uint16 soundFlags = 0x8000;
|
||||||
|
int16 blasterPort = 0;
|
||||||
|
int16 disableSoundCfg = 0;
|
||||||
|
|
||||||
|
//char playingSound = 0;
|
||||||
|
|
||||||
|
/* Mouse */
|
||||||
|
int16 disableMouseCfg = 0;
|
||||||
|
|
||||||
|
int16 mouseXShift = 3;
|
||||||
|
int16 mouseYShift = 3;
|
||||||
|
|
||||||
|
int16 mouseMaxCol = 320;
|
||||||
|
int16 mouseMaxRow = 200;
|
||||||
|
|
||||||
|
/* Language */
|
||||||
|
uint16 disableLangCfg = 0x8000;
|
||||||
|
uint16 language = 0x8000;
|
||||||
|
|
||||||
|
/* Configuration */
|
||||||
|
char batFileName[8];
|
||||||
|
|
||||||
|
/* */
|
||||||
|
int16 requiredSpace = 0;
|
||||||
|
|
||||||
|
/* Timer variables */
|
||||||
|
int32 startTime = 0;
|
||||||
|
char timer_enabled = 0;
|
||||||
|
int16 timer_delta = 1000;
|
||||||
|
|
||||||
|
int16 frameWaitTime = 0;
|
||||||
|
int32 startFrameTime = 0;
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
int16 allocatedBlocks[2] = { 0, 0 };
|
||||||
|
char *heapHeads[2] = { 0, 0 };
|
||||||
|
char *heapFence = 0;
|
||||||
|
int32 heapSize = 10000000;
|
||||||
|
char inAllocSub = 0;
|
||||||
|
|
||||||
|
/* Runtime */
|
||||||
|
//CleanupFuncPtr soundCleanup = 0;
|
||||||
|
|
||||||
|
/* Timer and delays */
|
||||||
|
int16 delayTime = 0;
|
||||||
|
int16 fastComputer = 1;
|
||||||
|
|
||||||
|
/* Joystick */
|
||||||
|
char useJoystick = 1;
|
||||||
|
|
||||||
|
/* Files */
|
||||||
|
int16 filesCount = 0;
|
||||||
|
File filesHandles[MAX_FILES];
|
||||||
|
|
||||||
|
/* Data files */
|
||||||
|
struct ChunkDesc *dataFiles[MAX_DATA_FILES];
|
||||||
|
int16 numDataChunks[MAX_DATA_FILES];
|
||||||
|
int16 dataFileHandles[MAX_DATA_FILES];
|
||||||
|
int32 chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
int32 chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
int32 chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
char isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
int32 packedSize = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int16 sprAllocated = 0;
|
||||||
|
|
||||||
|
SurfaceDesc primarySurfDesc;
|
||||||
|
SurfaceDesc *pPrimarySurfDesc;
|
||||||
|
|
||||||
|
int16 primaryWidth;
|
||||||
|
int16 primaryHeight;
|
||||||
|
|
||||||
|
int16 doRangeClamp = 0;
|
||||||
|
|
||||||
|
DrawPackedSpriteFunc pDrawPacked;
|
||||||
|
|
||||||
|
char redPalette[256];
|
||||||
|
char greenPalette[256];
|
||||||
|
char bluePalette[256];
|
||||||
|
|
||||||
|
int16 setAllPalette = 0;
|
||||||
|
|
||||||
|
int16 oldMode = 3;
|
||||||
|
int16 needDriverInit = 1;
|
||||||
|
char dontSetPalette = 0;
|
||||||
|
SurfaceDesc *curPrimaryDesc = 0;
|
||||||
|
SurfaceDesc *allocatedPrimary = 0;
|
||||||
|
|
||||||
|
PalDesc *pPaletteDesc = 0;
|
||||||
|
|
||||||
|
FileHandler pFileHandler = 0;
|
||||||
|
|
||||||
|
int16 unusedPalette1[18] = {
|
||||||
|
0, 0x0b, 0, 0x5555, 0xAAAA, 0xFFFF, 0, 0x5555, 0xAAAA, 0xFFFF, 0,
|
||||||
|
0x5555,
|
||||||
|
0xAAAA, 0xFFFF, 0, 0x5555, 0xAAAA, 0xFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
int16 unusedPalette2[] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||||
|
};
|
||||||
|
|
||||||
|
Color vgaPalette[16] = {
|
||||||
|
{0x00, 0x00, 0x00},
|
||||||
|
{0x00, 0x00, 0x2a},
|
||||||
|
{0x00, 0x2a, 0x00},
|
||||||
|
{0x00, 0x2a, 0x2a},
|
||||||
|
{0x2a, 0x00, 0x00},
|
||||||
|
{0x2a, 0x00, 0x2a},
|
||||||
|
{0x2a, 0x15, 0x00},
|
||||||
|
{0x2a, 0x2a, 0x2a},
|
||||||
|
{0x15, 0x15, 0x15},
|
||||||
|
{0x15, 0x15, 0x3f},
|
||||||
|
{0x15, 0x3f, 0x15},
|
||||||
|
{0x15, 0x3f, 0x3f},
|
||||||
|
{0x3f, 0x15, 0x15},
|
||||||
|
{0x3f, 0x15, 0x3f},
|
||||||
|
{0x3f, 0x3f, 0x15},
|
||||||
|
{0x3f, 0x3f, 0x3f}
|
||||||
|
};
|
||||||
|
|
||||||
|
PalDesc paletteStruct;
|
||||||
|
|
||||||
|
int16 debugFlag = 0;
|
||||||
|
int16 breakSet = 0;
|
||||||
|
int16 inVM = 0;
|
||||||
|
int16 colorCount = 16;
|
||||||
|
|
||||||
|
int16 slowCD = 0;
|
||||||
|
int16 checkMemFlag = 0;
|
||||||
|
|
||||||
|
int16 trySmallForBig = 0;
|
||||||
|
|
||||||
|
char inter_resStr[200];
|
||||||
|
int32 inter_resVal = 0;
|
||||||
|
|
||||||
|
char *inter_variables = 0;
|
||||||
|
char *inter_execPtr = 0;
|
||||||
|
int16 inter_animDataSize = 10;
|
||||||
|
|
||||||
|
int16 inter_mouseX = 0;
|
||||||
|
int16 inter_mouseY = 0;
|
||||||
|
|
||||||
|
char *tmpPalBuffer = 0;
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
191
gob/global.h
Normal file
191
gob/global.h
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef _GLOBAL_H
|
||||||
|
#define _GLOBAL_H
|
||||||
|
|
||||||
|
#include "gob/dataio.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
extern char pressedKeys[128];
|
||||||
|
|
||||||
|
extern char useMouse;
|
||||||
|
extern int16 mousePresent;
|
||||||
|
|
||||||
|
extern int16 presentCGA;
|
||||||
|
extern int16 presentEGA;
|
||||||
|
extern int16 presentVGA;
|
||||||
|
extern int16 presentHER;
|
||||||
|
|
||||||
|
extern int16 videoMode;
|
||||||
|
|
||||||
|
extern int16 disableVideoCfg;
|
||||||
|
|
||||||
|
#define VIDMODE_CGA 0x05
|
||||||
|
#define VIDMODE_EGA 0x0d
|
||||||
|
#define VIDMODE_VGA 0x13
|
||||||
|
#define VIDMODE_HER 7
|
||||||
|
|
||||||
|
extern uint16 presentSound;
|
||||||
|
extern uint16 soundFlags;
|
||||||
|
extern int16 disableSoundCfg;
|
||||||
|
//extern int16 blasterPort;
|
||||||
|
|
||||||
|
#define PROAUDIO_FLAG 0x10
|
||||||
|
#define ADLIB_FLAG 0x08
|
||||||
|
#define BLASTER_FLAG 0x04
|
||||||
|
#define INTERSOUND_FLAG 0x02
|
||||||
|
#define SPEAKER_FLAG 0x01
|
||||||
|
#define MIDI_FLAG 0x4000
|
||||||
|
|
||||||
|
extern uint16 disableLangCfg;
|
||||||
|
extern uint16 language;
|
||||||
|
|
||||||
|
#define NO 0
|
||||||
|
#define YES 1
|
||||||
|
#define UNDEF 2
|
||||||
|
|
||||||
|
#define F1_KEY 0x3b00
|
||||||
|
#define F2_KEY 0x3c00
|
||||||
|
#define F3_KEY 0x3d00
|
||||||
|
#define F4_KEY 0x3e00
|
||||||
|
#define F5_KEY 0x3f00
|
||||||
|
#define F6_KEY 0x4000
|
||||||
|
#define ESCAPE 0x001b
|
||||||
|
#define ENTER 0x000d
|
||||||
|
|
||||||
|
/* Configuration */
|
||||||
|
extern char batFileName[8];
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
extern int16 requiredSpace;
|
||||||
|
|
||||||
|
/* Timer variables */
|
||||||
|
extern int32 startTime;
|
||||||
|
extern char timer_enabled;
|
||||||
|
extern int16 timer_delta;
|
||||||
|
|
||||||
|
extern int16 frameWaitTime;
|
||||||
|
extern int32 startFrameTime;
|
||||||
|
|
||||||
|
/* Mouse */
|
||||||
|
extern int16 disableMouseCfg;
|
||||||
|
|
||||||
|
extern int16 mouseXShift;
|
||||||
|
extern int16 mouseYShift;
|
||||||
|
extern int16 mouseMaxCol;
|
||||||
|
extern int16 mouseMaxRow;
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
extern int16 allocatedBlocks[2];
|
||||||
|
extern char *heapHeads[2];
|
||||||
|
extern int32 heapSize;
|
||||||
|
extern char *heapFence;
|
||||||
|
extern char inAllocSub;
|
||||||
|
|
||||||
|
/* Timer and delays */
|
||||||
|
extern int16 delayTime;
|
||||||
|
extern int16 fastComputer;
|
||||||
|
|
||||||
|
/* Joystick */
|
||||||
|
extern char useJoystick;
|
||||||
|
|
||||||
|
/* Files */
|
||||||
|
#define MAX_FILES 30
|
||||||
|
|
||||||
|
extern int16 filesCount;
|
||||||
|
extern File filesHandles[MAX_FILES];
|
||||||
|
|
||||||
|
/* Data files */
|
||||||
|
extern struct ChunkDesc *dataFiles[MAX_DATA_FILES];
|
||||||
|
extern int16 numDataChunks[MAX_DATA_FILES];
|
||||||
|
extern int16 dataFileHandles[MAX_DATA_FILES];
|
||||||
|
extern int32 chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
extern int32 chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
extern int32 chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
extern char isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
|
||||||
|
extern int32 packedSize;
|
||||||
|
|
||||||
|
/* Video drivers */
|
||||||
|
#define UNK_DRIVER 0
|
||||||
|
#define VGA_DRIVER 1
|
||||||
|
#define EGA_DRIVER 2
|
||||||
|
#define CGA_DRIVER 3
|
||||||
|
#define HER_DRIVER 4
|
||||||
|
|
||||||
|
extern SurfaceDesc primarySurfDesc;
|
||||||
|
extern SurfaceDesc *pPrimarySurfDesc;
|
||||||
|
extern int16 sprAllocated;
|
||||||
|
|
||||||
|
extern int16 primaryWidth;
|
||||||
|
extern int16 primaryHeight;
|
||||||
|
|
||||||
|
extern int16 doRangeClamp;
|
||||||
|
|
||||||
|
extern DrawPackedSpriteFunc pDrawPacked;
|
||||||
|
|
||||||
|
extern char redPalette[256];
|
||||||
|
extern char greenPalette[256];
|
||||||
|
extern char bluePalette[256];
|
||||||
|
|
||||||
|
extern int16 setAllPalette;
|
||||||
|
|
||||||
|
extern SurfaceDesc *curPrimaryDesc;
|
||||||
|
extern SurfaceDesc *allocatedPrimary;
|
||||||
|
|
||||||
|
extern int16 oldMode;
|
||||||
|
extern int16 needDriverInit;
|
||||||
|
extern char dontSetPalette;
|
||||||
|
|
||||||
|
extern PalDesc *pPaletteDesc;
|
||||||
|
|
||||||
|
typedef void (*FileHandler) (char *path);
|
||||||
|
extern FileHandler pFileHandler;
|
||||||
|
|
||||||
|
//extern void interrupt(*oldInt5Handler) (void);
|
||||||
|
//extern void interrupt(*oldInt0Handler) (void);
|
||||||
|
//extern void interrupt(*oldInt1bHandler) (void);
|
||||||
|
|
||||||
|
extern int16 unusedPalette1[18];
|
||||||
|
extern int16 unusedPalette2[16];
|
||||||
|
extern Color vgaPalette[16];
|
||||||
|
extern PalDesc paletteStruct;
|
||||||
|
|
||||||
|
extern int16 debugFlag;
|
||||||
|
extern int16 breakSet;
|
||||||
|
extern int16 inVM;
|
||||||
|
extern int16 colorCount;
|
||||||
|
|
||||||
|
extern int16 trySmallForBig;
|
||||||
|
extern int16 checkMemFlag;
|
||||||
|
|
||||||
|
extern char inter_resStr[200];
|
||||||
|
extern int32 inter_resVal;
|
||||||
|
|
||||||
|
extern char *inter_variables;
|
||||||
|
extern char *inter_execPtr;
|
||||||
|
extern int16 inter_animDataSize;
|
||||||
|
|
||||||
|
extern int16 inter_mouseX;
|
||||||
|
extern int16 inter_mouseY;
|
||||||
|
|
||||||
|
extern char *tmpPalBuffer;
|
||||||
|
|
||||||
|
typedef struct Rectangle {
|
||||||
|
int16 left;
|
||||||
|
int16 top;
|
||||||
|
int16 width;
|
||||||
|
int16 height;
|
||||||
|
} Rectangle;
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
130
gob/gob.cpp
Normal file
130
gob/gob.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 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
|
||||||
|
* aint32 with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* $Header$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "base/gameDetector.h"
|
||||||
|
#include "base/plugins.h"
|
||||||
|
#include "backends/fs/fs.h"
|
||||||
|
|
||||||
|
#include "gob/gob.h"
|
||||||
|
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/game.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
#include "gob/init.h"
|
||||||
|
|
||||||
|
static const GameSettings gob_games[] = {
|
||||||
|
{"gob1", "Gobliiins", 0},
|
||||||
|
{0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameList Engine_GOB_gameList() {
|
||||||
|
GameList games;
|
||||||
|
const GameSettings *g = gob_games;
|
||||||
|
|
||||||
|
while (g->name) {
|
||||||
|
games.push_back(*g);
|
||||||
|
g++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
|
||||||
|
DetectedGameList Engine_GOB_detectGames(const FSList &fslist) {
|
||||||
|
DetectedGameList detectedGames;
|
||||||
|
|
||||||
|
return detectedGames;
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine *Engine_GOB_create(GameDetector * detector, OSystem *syst) {
|
||||||
|
return new Gob::GobEngine(detector, syst);
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_PLUGIN(GOB, "Gob Engine")
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
#define MAX_TIME_DELTA 100
|
||||||
|
GobEngine *_vm = NULL;
|
||||||
|
|
||||||
|
GobEngine::GobEngine(GameDetector *detector, OSystem * syst) : Engine(syst) {
|
||||||
|
|
||||||
|
// Setup mixer
|
||||||
|
if (!_mixer->isReady()) {
|
||||||
|
warning("Sound initialization failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_mixer->setVolumeForSoundType(SoundMixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
||||||
|
_mixer->setVolumeForSoundType(SoundMixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
||||||
|
|
||||||
|
_vm = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GobEngine::~GobEngine() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void GobEngine::errorString(const char *buf1, char *buf2) {
|
||||||
|
strcpy(buf2, buf1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GobEngine::init(GameDetector &detector) {
|
||||||
|
debugFlag = 1;
|
||||||
|
breakSet = 0;
|
||||||
|
doRangeClamp = 1;
|
||||||
|
trySmallForBig = 0;
|
||||||
|
|
||||||
|
checkMemFlag = 0;
|
||||||
|
videoMode = 0x13;
|
||||||
|
snd_soundPort = 1;
|
||||||
|
useMouse = 1;
|
||||||
|
soundFlags = 0;
|
||||||
|
language = 5;
|
||||||
|
|
||||||
|
init_initGame(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GobEngine::go() {
|
||||||
|
int msec = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
OSystem::Event event;
|
||||||
|
while (g_system->pollEvent(event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case OSystem::EVENT_QUIT:
|
||||||
|
g_system->quit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug(0, "Main loop");
|
||||||
|
_system->delayMillis(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GobEngine::shutdown() {
|
||||||
|
_system->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
51
gob/gob.h
Normal file
51
gob/gob.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 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$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __Gob_H
|
||||||
|
#define __Gob_H
|
||||||
|
|
||||||
|
#include "common/stdafx.h"
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "sound/mixer.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
|
#include "base/engine.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
class GobEngine : public Engine {
|
||||||
|
void errorString(const char *buf_input, char *buf_output);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int go();
|
||||||
|
int init(GameDetector &detector);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GobEngine(GameDetector * detector, OSystem * syst);
|
||||||
|
virtual ~GobEngine();
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
#endif
|
3320
gob/goblin.cpp
Normal file
3320
gob/goblin.cpp
Normal file
File diff suppressed because it is too large
Load diff
192
gob/goblin.h
Normal file
192
gob/goblin.h
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __GOBLIN_H
|
||||||
|
#define __GOBLIN_H
|
||||||
|
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#define TYPE_USUAL 0
|
||||||
|
#define TYPE_AMORPHOUS 1
|
||||||
|
#define TYPE_MOBILE 3
|
||||||
|
|
||||||
|
#pragma START_PACK_STRUCTS
|
||||||
|
typedef struct Gob_State {
|
||||||
|
int16 animation;// +0h
|
||||||
|
int16 layer; // +2h
|
||||||
|
int16 unk0; // +4h
|
||||||
|
int16 unk1; // +6h
|
||||||
|
int16 sndItem; // +8h, high/low byte - sound sample index
|
||||||
|
int16 freq; // +Ah, high/low byte * 100 - frequency
|
||||||
|
int16 repCount; // +Ch high/low byte - repeat count
|
||||||
|
int16 unk2; // +Eh
|
||||||
|
} GCC_PACK Gob_State;
|
||||||
|
|
||||||
|
typedef struct Gob_State *Gob_PState;
|
||||||
|
|
||||||
|
#define szGob_StateLine 24
|
||||||
|
typedef Gob_PState Gob_StateLine[6];
|
||||||
|
|
||||||
|
typedef struct Gob_Object {
|
||||||
|
int16 animation; // +0h
|
||||||
|
int16 state; // +2h
|
||||||
|
int16 stateColumn; // +4h
|
||||||
|
int16 curFrame; // +6h
|
||||||
|
int16 xPos; // +8h
|
||||||
|
int16 yPos; // +Ah
|
||||||
|
int16 dirtyLeft; // +Ch
|
||||||
|
int16 dirtyTop; // +Eh
|
||||||
|
int16 dirtyRight; // +10h
|
||||||
|
int16 dirtyBottom; // +12h
|
||||||
|
int16 left; // +14h
|
||||||
|
int16 top; // +16h
|
||||||
|
int16 right; // +18h
|
||||||
|
int16 bottom; // +1ah
|
||||||
|
int16 nextState; // +1ch
|
||||||
|
int16 multState; // +1eh
|
||||||
|
int16 actionStartState; // +20h
|
||||||
|
int16 curLookDir; // +22h
|
||||||
|
int16 pickable; // +24h
|
||||||
|
int16 relaxTime; // +26h
|
||||||
|
Gob_StateLine *stateMach; // +28h
|
||||||
|
Gob_StateLine *realStateMach; // +2ch
|
||||||
|
char doAnim; // +30h
|
||||||
|
char order; // +31h
|
||||||
|
char noTick; // +32h
|
||||||
|
char toRedraw; // +33h
|
||||||
|
char type; // +34h
|
||||||
|
char maxTick; // +35h
|
||||||
|
char tick; // +36h
|
||||||
|
char multObjIndex; // +37h, from which play mult animations
|
||||||
|
char unk14; // +38h
|
||||||
|
char visible; // +39h
|
||||||
|
} GCC_PACK Gob_Object;
|
||||||
|
|
||||||
|
typedef struct Gob_Pos {
|
||||||
|
char x;
|
||||||
|
char y;
|
||||||
|
} GCC_PACK Gob_Pos;
|
||||||
|
#pragma END_PACK_STRUCTS
|
||||||
|
|
||||||
|
extern Util_List *gob_objList;
|
||||||
|
extern Gob_Object *gob_goblins[4];
|
||||||
|
extern int16 gob_currentGoblin;
|
||||||
|
extern Snd_SoundDesc *gob_soundData[16];
|
||||||
|
extern int16 gob_gobStateLayer;
|
||||||
|
extern char gob_goesAtTarget;
|
||||||
|
extern char gob_readyToAct;
|
||||||
|
extern int16 gob_gobAction; // 0 - move, 3 - do action, 4 - pick
|
||||||
|
// goblins 0 - picker, 1 - fighter, 2 - mage
|
||||||
|
extern Gob_Pos gob_gobPositions[3];
|
||||||
|
extern int16 gob_gobDestX;
|
||||||
|
extern int16 gob_gobDestY;
|
||||||
|
extern int16 gob_pressedMapX;
|
||||||
|
extern int16 gob_pressedMapY;
|
||||||
|
extern char gob_pathExistence;
|
||||||
|
|
||||||
|
// Pointers to interpreter variables
|
||||||
|
extern int32 *gob_some0ValPtr;
|
||||||
|
|
||||||
|
extern int32 *gob_gobRetVarPtr;
|
||||||
|
extern int32 *gob_curGobVarPtr;
|
||||||
|
extern int32 *gob_curGobXPosVarPtr;
|
||||||
|
extern int32 *gob_curGobYPosVarPtr;
|
||||||
|
extern int32 *gob_itemInPocketVarPtr;
|
||||||
|
|
||||||
|
extern int32 *gob_curGobStateVarPtr;
|
||||||
|
extern int32 *gob_curGobFrameVarPtr;
|
||||||
|
extern int32 *gob_curGobMultStateVarPtr;
|
||||||
|
extern int32 *gob_curGobNextStateVarPtr;
|
||||||
|
extern int32 *gob_curGobScrXVarPtr;
|
||||||
|
extern int32 *gob_curGobScrYVarPtr;
|
||||||
|
extern int32 *gob_curGobLeftVarPtr;
|
||||||
|
extern int32 *gob_curGobTopVarPtr;
|
||||||
|
extern int32 *gob_curGobRightVarPtr;
|
||||||
|
extern int32 *gob_curGobBottomVarPtr;
|
||||||
|
extern int32 *gob_curGobDoAnimVarPtr;
|
||||||
|
extern int32 *gob_curGobOrderVarPtr;
|
||||||
|
extern int32 *gob_curGobNoTickVarPtr;
|
||||||
|
extern int32 *gob_curGobTypeVarPtr;
|
||||||
|
extern int32 *gob_curGobMaxTickVarPtr;
|
||||||
|
extern int32 *gob_curGobTickVarPtr;
|
||||||
|
extern int32 *gob_curGobActStartStateVarPtr;
|
||||||
|
extern int32 *gob_curGobLookDirVarPtr;
|
||||||
|
extern int32 *gob_curGobPickableVarPtr;
|
||||||
|
extern int32 *gob_curGobRelaxVarPtr;
|
||||||
|
extern int32 *gob_curGobMaxFrameVarPtr;
|
||||||
|
|
||||||
|
extern int32 *gob_destItemStateVarPtr;
|
||||||
|
extern int32 *gob_destItemFrameVarPtr;
|
||||||
|
extern int32 *gob_destItemMultStateVarPtr;
|
||||||
|
extern int32 *gob_destItemNextStateVarPtr;
|
||||||
|
extern int32 *gob_destItemScrXVarPtr;
|
||||||
|
extern int32 *gob_destItemScrYVarPtr;
|
||||||
|
extern int32 *gob_destItemLeftVarPtr;
|
||||||
|
extern int32 *gob_destItemTopVarPtr;
|
||||||
|
extern int32 *gob_destItemRightVarPtr;
|
||||||
|
extern int32 *gob_destItemBottomVarPtr;
|
||||||
|
extern int32 *gob_destItemDoAnimVarPtr;
|
||||||
|
extern int32 *gob_destItemOrderVarPtr;
|
||||||
|
extern int32 *gob_destItemNoTickVarPtr;
|
||||||
|
extern int32 *gob_destItemTypeVarPtr;
|
||||||
|
extern int32 *gob_destItemMaxTickVarPtr;
|
||||||
|
extern int32 *gob_destItemTickVarPtr;
|
||||||
|
extern int32 *gob_destItemActStartStVarPtr;
|
||||||
|
extern int32 *gob_destItemLookDirVarPtr;
|
||||||
|
extern int32 *gob_destItemPickableVarPtr;
|
||||||
|
extern int32 *gob_destItemRelaxVarPtr;
|
||||||
|
extern int32 *gob_destItemMaxFrameVarPtr;
|
||||||
|
|
||||||
|
extern int16 gob_destItemType;
|
||||||
|
extern int16 gob_destItemState;
|
||||||
|
extern int16 gob_itemToObject[20];
|
||||||
|
extern Gob_Object *gob_objects[20];
|
||||||
|
extern int16 gob_objCount;
|
||||||
|
extern int16 gob_gobsCount;
|
||||||
|
extern int16 gob_itemIndInPocket;
|
||||||
|
extern int16 gob_itemIdInPocket;
|
||||||
|
extern char gob_itemByteFlag;
|
||||||
|
extern int16 gob_destItemId;
|
||||||
|
extern int16 gob_destActionItem;
|
||||||
|
extern Gob_Object *gob_actDestItemDesc;
|
||||||
|
extern int16 gob_forceNextState[10];
|
||||||
|
extern char gob_boreCounter;
|
||||||
|
extern int16 gob_positionedGob;
|
||||||
|
extern char gob_noPick;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
char gob_rotateState(int16 from, int16 to);
|
||||||
|
void gob_playSound(Snd_SoundDesc * snd, int16 repCount, int16 freq);
|
||||||
|
void gob_drawObjects(void);
|
||||||
|
void gob_animateObjects(void);
|
||||||
|
void gob_placeObject(Gob_Object * objDesc, char animated);
|
||||||
|
int16 gob_getObjMaxFrame(Gob_Object * obj);
|
||||||
|
int16 gob_objIntersected(Gob_Object * obj1, Gob_Object * obj2);
|
||||||
|
void gob_setMultStates(Gob_Object * gobDesc);
|
||||||
|
int16 gob_nextLayer(Gob_Object * gobDesc);
|
||||||
|
void gob_showBoredom(int16 gobIndex);
|
||||||
|
void gob_switchGoblin(int16 index);
|
||||||
|
void gob_freeObjects(void);
|
||||||
|
void gob_zeroObjects(void);
|
||||||
|
void gob_freeAllObjects(void);
|
||||||
|
void gob_loadObjects(char *source);
|
||||||
|
void gob_initVarPointers(void);
|
||||||
|
void gob_saveGobDataToVars(int16 xPos, int16 yPos, int16 someVal);
|
||||||
|
void gob_loadGobDataFromVars(void);
|
||||||
|
void gob_pickItem(int16 indexToPocket, int16 idToPocket);
|
||||||
|
void gob_placeItem(int16 indexInPocket, int16 idInPocket);
|
||||||
|
void gob_swapItems(int16 indexToPick, int16 idToPick);
|
||||||
|
void gob_treatItemPick(int16 itemId);
|
||||||
|
int16 gob_treatItem(int16 action);
|
||||||
|
void gob_interFunc(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __GOBLIN_H */
|
293
gob/init.cpp
Normal file
293
gob/init.cpp
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/dataio.h"
|
||||||
|
#include "gob/resource.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/init.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
#include "gob/timer.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
#include "gob/game.h"
|
||||||
|
#include "gob/draw.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void game_start(void);
|
||||||
|
|
||||||
|
extern int16 debugFlag;
|
||||||
|
extern int16 inVM;
|
||||||
|
extern int16 colorCount;
|
||||||
|
|
||||||
|
PalDesc *init_palDesc;
|
||||||
|
|
||||||
|
static const char *init_fontNames[] =
|
||||||
|
{ "jeulet1.let", "jeulet2.let", "jeucar1.let", "jeumath.let" };
|
||||||
|
|
||||||
|
void init_findBestCfg(void) {
|
||||||
|
videoMode = VIDMODE_VGA;
|
||||||
|
useMouse = mousePresent;
|
||||||
|
if (presentSound & BLASTER_FLAG)
|
||||||
|
soundFlags = BLASTER_FLAG | SPEAKER_FLAG | MIDI_FLAG;
|
||||||
|
else if (presentSound & PROAUDIO_FLAG)
|
||||||
|
soundFlags = PROAUDIO_FLAG | SPEAKER_FLAG | MIDI_FLAG;
|
||||||
|
else if (presentSound & ADLIB_FLAG)
|
||||||
|
soundFlags = ADLIB_FLAG | SPEAKER_FLAG | MIDI_FLAG;
|
||||||
|
else if (presentSound & INTERSOUND_FLAG)
|
||||||
|
soundFlags = INTERSOUND_FLAG | SPEAKER_FLAG;
|
||||||
|
else if (presentSound & SPEAKER_FLAG)
|
||||||
|
soundFlags = SPEAKER_FLAG;
|
||||||
|
else
|
||||||
|
soundFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_soundVideo(int32 smallHeap, int16 flag) {
|
||||||
|
if (videoMode != 0x13 && videoMode != 0)
|
||||||
|
error("init_soundVideo: Video mode 0x%x is not supported!",
|
||||||
|
videoMode);
|
||||||
|
|
||||||
|
pFileHandler = 0;
|
||||||
|
srand(0);
|
||||||
|
|
||||||
|
//if ((flag & 4) == 0)
|
||||||
|
// vid_findVideo();
|
||||||
|
|
||||||
|
mousePresent = 1;
|
||||||
|
|
||||||
|
inVM = 0;
|
||||||
|
|
||||||
|
presentSound = 0; // FIXME: sound is not supported yet
|
||||||
|
|
||||||
|
sprAllocated = 0;
|
||||||
|
filesCount = 0;
|
||||||
|
timer_enableTimer();
|
||||||
|
|
||||||
|
// snd_setResetTimerFlag(debugFlag); // TODO
|
||||||
|
|
||||||
|
if (videoMode == 0x13)
|
||||||
|
colorCount = 256;
|
||||||
|
fastComputer = 1;
|
||||||
|
|
||||||
|
pPaletteDesc = &paletteStruct;
|
||||||
|
pPaletteDesc->vgaPal = vgaPalette;
|
||||||
|
pPaletteDesc->unused1 = unusedPalette1;
|
||||||
|
pPaletteDesc->unused2 = unusedPalette2;
|
||||||
|
pPrimarySurfDesc = &primarySurfDesc;
|
||||||
|
|
||||||
|
if (videoMode != 0)
|
||||||
|
vid_initSurfDesc(videoMode, 320, 200, PRIMARY_SURFACE);
|
||||||
|
|
||||||
|
if (soundFlags & MIDI_FLAG) {
|
||||||
|
soundFlags &= presentSound;
|
||||||
|
if (presentSound & ADLIB_FLAG)
|
||||||
|
soundFlags |= MIDI_FLAG;
|
||||||
|
} else {
|
||||||
|
soundFlags &= presentSound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_cleanup(void) {
|
||||||
|
if (debugFlag == 0)
|
||||||
|
timer_disableTimer();
|
||||||
|
|
||||||
|
vid_freeDriver();
|
||||||
|
if (curPrimaryDesc != 0) {
|
||||||
|
vid_freeSurfDesc(curPrimaryDesc);
|
||||||
|
vid_freeSurfDesc(allocatedPrimary);
|
||||||
|
allocatedPrimary = 0;
|
||||||
|
curPrimaryDesc = 0;
|
||||||
|
}
|
||||||
|
pPrimarySurfDesc = 0;
|
||||||
|
if (snd_cleanupFunc != 0 && snd_playingSound != 0) {
|
||||||
|
(*snd_cleanupFunc) (0);
|
||||||
|
snd_cleanupFunc = 0;
|
||||||
|
}
|
||||||
|
snd_speakerOff();
|
||||||
|
|
||||||
|
data_closeDataFile();
|
||||||
|
if (filesCount != 0)
|
||||||
|
error("init_cleanup: Error! Opened files lef: %d", filesCount);
|
||||||
|
|
||||||
|
if (sprAllocated != 0)
|
||||||
|
error("init_cleanup: Error! Allocated sprites left: %d",
|
||||||
|
sprAllocated);
|
||||||
|
|
||||||
|
if (allocatedBlocks[0] != 0)
|
||||||
|
error("init_cleanup: Error! Allocated blocks in heap 0 left: %d",
|
||||||
|
allocatedBlocks[0]);
|
||||||
|
|
||||||
|
if (allocatedBlocks[1] != 0)
|
||||||
|
error("init_cleanup: Error! Allocated blocks in heap 1 left: %d",
|
||||||
|
allocatedBlocks[1]);
|
||||||
|
|
||||||
|
snd_stopSound(0);
|
||||||
|
keyboard_release();
|
||||||
|
//free(heapHeads);
|
||||||
|
g_system->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static void init_hardErrHandler(void) {
|
||||||
|
hardretn(-1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void init_initGame(char *totName) {
|
||||||
|
int16 handle2;
|
||||||
|
int16 i;
|
||||||
|
int16 handle;
|
||||||
|
char *infBuf;
|
||||||
|
char *infPtr;
|
||||||
|
char *infEnd;
|
||||||
|
int16 j;
|
||||||
|
char buffer[20];
|
||||||
|
int32 varsCount;
|
||||||
|
/*
|
||||||
|
src = byte ptr -2Eh
|
||||||
|
var_1A = word ptr -1Ah
|
||||||
|
var_18 = word ptr -18h
|
||||||
|
var_16 = dword ptr -16h
|
||||||
|
var_12 = word ptr -12h
|
||||||
|
var_10 = word ptr -10h
|
||||||
|
handle2 = word ptr -0Eh
|
||||||
|
fileHandle = word ptr -0Ch
|
||||||
|
numFromTot = word ptr -0Ah
|
||||||
|
memAvail = dword ptr -6
|
||||||
|
memBlocks = word ptr -2*/
|
||||||
|
|
||||||
|
language = 5;
|
||||||
|
disableVideoCfg = 0x11;
|
||||||
|
disableMouseCfg = 0x15;
|
||||||
|
//reqRAMParag = 570;
|
||||||
|
//requiredSpace = 10;
|
||||||
|
strcpy(batFileName, "go");
|
||||||
|
init_soundVideo(1000, 1);
|
||||||
|
language = 2;
|
||||||
|
|
||||||
|
handle2 = data_openData("intro.stk");
|
||||||
|
if (handle2 >= 0) {
|
||||||
|
data_closeData(handle2);
|
||||||
|
data_openDataFile("intro.stk");
|
||||||
|
}
|
||||||
|
|
||||||
|
util_initInput();
|
||||||
|
|
||||||
|
vid_setHandlers();
|
||||||
|
vid_initPrimary(videoMode);
|
||||||
|
// harderr(&init_hardErrHandler);
|
||||||
|
mouseXShift = 1;
|
||||||
|
mouseYShift = 1;
|
||||||
|
|
||||||
|
game_totTextData = 0;
|
||||||
|
game_totFileData = 0;
|
||||||
|
game_totResourceTable = 0;
|
||||||
|
inter_variables = 0;
|
||||||
|
init_palDesc = (PalDesc *)malloc(12);
|
||||||
|
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
error("init_initGame: Only 0x13 video mode is supported!");
|
||||||
|
|
||||||
|
init_palDesc->vgaPal = draw_vgaPalette;
|
||||||
|
init_palDesc->unused1 = draw_unusedPalette1;
|
||||||
|
init_palDesc->unused2 = draw_unusedPalette2;
|
||||||
|
vid_setFullPalette(init_palDesc);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
draw_fonts[i] = 0;
|
||||||
|
|
||||||
|
handle = data_openData("intro.inf");
|
||||||
|
|
||||||
|
if (handle < 0) {
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
handle2 = data_openData(init_fontNames[i]);
|
||||||
|
if (handle2 >= 0) {
|
||||||
|
data_closeData(handle2);
|
||||||
|
draw_fonts[i] =
|
||||||
|
util_loadFont(init_fontNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data_closeData(handle);
|
||||||
|
|
||||||
|
infPtr = data_getData("intro.inf");
|
||||||
|
infBuf = infPtr;
|
||||||
|
|
||||||
|
infEnd = infBuf + data_getDataSize("intro.inf");
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++, infPtr++) {
|
||||||
|
for (j = 0; *infPtr >= ' ' && infPtr != infEnd;
|
||||||
|
j++, infPtr++)
|
||||||
|
buffer[j] = *infPtr;
|
||||||
|
|
||||||
|
buffer[j] = 0;
|
||||||
|
strcat(buffer, ".let");
|
||||||
|
handle2 = data_openData(buffer);
|
||||||
|
if (handle2 >= 0) {
|
||||||
|
data_closeData(handle2);
|
||||||
|
draw_fonts[i] = util_loadFont(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infPtr == infEnd)
|
||||||
|
break;
|
||||||
|
|
||||||
|
infPtr++;
|
||||||
|
if (infPtr == infEnd)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(infBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totName != 0) {
|
||||||
|
strcpy(buffer, totName);
|
||||||
|
strcat(buffer, ".tot");
|
||||||
|
} else {
|
||||||
|
strcpy(buffer, "intro.tot");
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = data_openData(buffer);
|
||||||
|
|
||||||
|
if (handle >= 0) {
|
||||||
|
// Get variables count
|
||||||
|
data_seekData(handle, 0x2c, SEEK_SET);
|
||||||
|
data_readData(handle, (char *)&varsCount, 4);
|
||||||
|
varsCount = FROM_LE_32(varsCount);
|
||||||
|
data_closeData(handle);
|
||||||
|
|
||||||
|
inter_variables = (char *)malloc(varsCount * 4);
|
||||||
|
memset(inter_variables, 0, varsCount * 4);
|
||||||
|
|
||||||
|
strcpy(game_curTotFile, buffer);
|
||||||
|
game_start();
|
||||||
|
|
||||||
|
if (inter_variables != 0)
|
||||||
|
free(inter_variables);
|
||||||
|
|
||||||
|
if (game_totFileData != 0)
|
||||||
|
free(game_totFileData);
|
||||||
|
|
||||||
|
if (game_totTextData != 0)
|
||||||
|
free((char *)game_totTextData);
|
||||||
|
|
||||||
|
if (game_totResourceTable != 0)
|
||||||
|
free((char *)game_totResourceTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (draw_fonts[i] != 0)
|
||||||
|
util_freeFont(draw_fonts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char *)init_palDesc);
|
||||||
|
data_closeDataFile();
|
||||||
|
vid_initPrimary(-1);
|
||||||
|
init_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
20
gob/init.h
Normal file
20
gob/init.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __INIT_H
|
||||||
|
#define __INIT_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void init_findBestCfg(void);
|
||||||
|
void init_soundVideo(int32 smallHeapSize, int16 flag);
|
||||||
|
|
||||||
|
void init_initGame(char *totFile);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
1496
gob/inter.cpp
Normal file
1496
gob/inter.cpp
Normal file
File diff suppressed because it is too large
Load diff
85
gob/inter.h
Normal file
85
gob/inter.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __INTERPRET_H
|
||||||
|
#define __INTERPRET_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
extern int16 inter_animPalLowIndex;
|
||||||
|
extern int16 inter_animPalHighIndex;
|
||||||
|
extern int16 inter_animPalDir;
|
||||||
|
extern uint32 inter_soundEndTimeKey;
|
||||||
|
extern int16 inter_soundStopVal;
|
||||||
|
extern char inter_terminate;
|
||||||
|
extern char inter_breakFlag;
|
||||||
|
extern int16 *inter_breakFromLevel;
|
||||||
|
extern int16 *inter_nestLevel;
|
||||||
|
|
||||||
|
int16 inter_load16(void);
|
||||||
|
int16 inter_peek16(char *ptr);
|
||||||
|
int32 inter_peek32(char *ptr);
|
||||||
|
|
||||||
|
void inter_setMousePos(void);
|
||||||
|
char inter_evalExpr(int16 *pRes);
|
||||||
|
char inter_evalBoolResult(void);
|
||||||
|
void inter_storeResult(void);
|
||||||
|
void inter_printText(void);
|
||||||
|
void inter_animPalette(void);
|
||||||
|
void inter_animPalInit(void);
|
||||||
|
void inter_loadMult(void);
|
||||||
|
void inter_playMult(void);
|
||||||
|
void inter_freeMult(void);
|
||||||
|
void inter_initCursor(void);
|
||||||
|
void inter_initCursorAnim(void);
|
||||||
|
void inter_clearCursorAnim(void);
|
||||||
|
void inter_drawOperations(void);
|
||||||
|
void inter_getFreeMem(void);
|
||||||
|
void inter_manageDataFile(void);
|
||||||
|
void inter_getFreeMem(void);
|
||||||
|
void inter_manageDataFile(void);
|
||||||
|
void inter_writeData(void);
|
||||||
|
void inter_checkData(void);
|
||||||
|
void inter_readData(void);
|
||||||
|
void inter_loadFont(void);
|
||||||
|
void inter_freeFont(void);
|
||||||
|
void inter_prepareStr(void);
|
||||||
|
void inter_insertStr(void);
|
||||||
|
void inter_cutStr(void);
|
||||||
|
void inter_strstr(void);
|
||||||
|
void inter_setFrameRate(void);
|
||||||
|
void inter_strlen(void);
|
||||||
|
void inter_strToLong(void);
|
||||||
|
void inter_invalidate(void);
|
||||||
|
void inter_loadSpriteContent(void);
|
||||||
|
void inter_copySprite(void);
|
||||||
|
void inter_putPixel(void);
|
||||||
|
void inter_fillRect(void);
|
||||||
|
void inter_drawLine(void);
|
||||||
|
void inter_createSprite(void);
|
||||||
|
void inter_freeSprite(void);
|
||||||
|
void inter_renewTimeInVars(void);
|
||||||
|
void inter_playComposition(void);
|
||||||
|
void inter_stopSound(void);
|
||||||
|
void inter_playSound(void);
|
||||||
|
void inter_loadCursor(void);
|
||||||
|
void inter_loadSpriteToPos(void);
|
||||||
|
void inter_funcBlock(int16 retFlag);
|
||||||
|
void inter_loadTot(void);
|
||||||
|
void inter_storeKey(int16 key);
|
||||||
|
void inter_keyFunc(void);
|
||||||
|
void inter_checkSwitchTable(char **ppExec);
|
||||||
|
void inter_repeatUntil(void);
|
||||||
|
void inter_whileDo(void);
|
||||||
|
void inter_funcBlock(int16 retFlag);
|
||||||
|
void inter_callSub(int16 retFlag);
|
||||||
|
void inter_initControlVars(void);
|
||||||
|
void inter_callSub(int16 retFlag);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
736
gob/map.cpp
Normal file
736
gob/map.cpp
Normal file
|
@ -0,0 +1,736 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/map.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/dataio.h"
|
||||||
|
#include "gob/inter.h"
|
||||||
|
#include "gob/goblin.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
char map_passMap[28][26]; // [y][x]
|
||||||
|
int16 map_itemsMap[28][26]; // [y][x]
|
||||||
|
|
||||||
|
Map_Point map_wayPoints[40];
|
||||||
|
int16 map_nearestWayPoint = 0;
|
||||||
|
int16 map_nearestDest = 0;
|
||||||
|
|
||||||
|
int16 map_curGoblinX;
|
||||||
|
int16 map_curGoblinY;
|
||||||
|
int16 map_destX;
|
||||||
|
int16 map_destY;
|
||||||
|
|
||||||
|
Map_ItemPos map_itemPoses[40];
|
||||||
|
char map_loadFromAvo;
|
||||||
|
char map_sourceFile[15];
|
||||||
|
char *map_avoDataPtr;
|
||||||
|
|
||||||
|
int16 map_getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
|
||||||
|
int16 dir;
|
||||||
|
|
||||||
|
dir = 0;
|
||||||
|
|
||||||
|
if (x0 == x1 && y0 == y1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (x1 < 0 || x1 > 25 || y1 < 0 || y1 > 27)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (y1 > y0)
|
||||||
|
dir = 8;
|
||||||
|
else if (y1 < y0)
|
||||||
|
dir = 2;
|
||||||
|
|
||||||
|
if (x1 > x0)
|
||||||
|
dir += 4;
|
||||||
|
else if (x1 < x0)
|
||||||
|
dir += 1;
|
||||||
|
|
||||||
|
if (map_passMap[y0][x0] == 3 && (dir == 3 || dir == 6 || dir == 2)) {
|
||||||
|
if (map_passMap[y0 - 1][x0] != 0)
|
||||||
|
return 0x4800;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_passMap[y0][x0] == 3 && (dir == 9 || dir == 12 || dir == 8)) {
|
||||||
|
if (map_passMap[y0 + 1][x0] != 0)
|
||||||
|
return 0x5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_passMap[y0][x0] == 6 && (dir == 3 || dir == 6 || dir == 2)) {
|
||||||
|
if (map_passMap[y0 - 1][x0] != 0)
|
||||||
|
return 0x4800;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_passMap[y0][x0] == 6 && (dir == 9 || dir == 12 || dir == 8)) {
|
||||||
|
if (map_passMap[y0 + 1][x0] != 0)
|
||||||
|
return 0x5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 1) {
|
||||||
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
||||||
|
return 0x4b00;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 4) {
|
||||||
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
||||||
|
return 0x4d00;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 2) {
|
||||||
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
||||||
|
return 0x4800;
|
||||||
|
|
||||||
|
if (y0 - 1 >= 0 && x0 - 1 >= 0
|
||||||
|
&& map_passMap[y0 - 1][x0 - 1] != 0)
|
||||||
|
return 0x4700;
|
||||||
|
|
||||||
|
if (y0 - 1 >= 0 && x0 + 1 < 26
|
||||||
|
&& map_passMap[y0 - 1][x0 + 1] != 0)
|
||||||
|
return 0x4900;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 8) {
|
||||||
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
||||||
|
return 0x5000;
|
||||||
|
|
||||||
|
if (y0 + 1 < 28 && x0 - 1 >= 0
|
||||||
|
&& map_passMap[y0 + 1][x0 - 1] != 0)
|
||||||
|
return 0x4f00;
|
||||||
|
|
||||||
|
if (y0 + 1 < 28 && x0 + 1 < 26
|
||||||
|
&& map_passMap[y0 + 1][x0 + 1] != 0)
|
||||||
|
return 0x5100;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 6) {
|
||||||
|
if (y0 - 1 >= 0 && x0 + 1 < 26
|
||||||
|
&& map_passMap[y0 - 1][x0 + 1] != 0)
|
||||||
|
return 0x4900;
|
||||||
|
|
||||||
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
||||||
|
return 0x4800;
|
||||||
|
|
||||||
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
||||||
|
return 0x4d00;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 12) {
|
||||||
|
if (x0 + 1 < 26 && y0 + 1 < 28
|
||||||
|
&& map_passMap[y0 + 1][x0 + 1] != 0)
|
||||||
|
return 0x5100;
|
||||||
|
|
||||||
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
||||||
|
return 0x5000;
|
||||||
|
|
||||||
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
||||||
|
return 0x4d00;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 3) {
|
||||||
|
if (x0 - 1 >= 0 && y0 - 1 >= 0
|
||||||
|
&& map_passMap[y0 - 1][x0 - 1] != 0)
|
||||||
|
return 0x4700;
|
||||||
|
|
||||||
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
||||||
|
return 0x4800;
|
||||||
|
|
||||||
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
||||||
|
return 0x4b00;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == 9) {
|
||||||
|
if (x0 - 1 >= 0 && y0 + 1 < 28
|
||||||
|
&& map_passMap[y0 + 1][x0 - 1] != 0)
|
||||||
|
return 0x4f00;
|
||||||
|
|
||||||
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
||||||
|
return 0x5000;
|
||||||
|
|
||||||
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
||||||
|
return 0x4b00;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_findNearestToGob(void) {
|
||||||
|
int16 length;
|
||||||
|
int16 i;
|
||||||
|
int16 tmp;
|
||||||
|
|
||||||
|
length = 30000;
|
||||||
|
|
||||||
|
for (i = 0; i < 40; i++) {
|
||||||
|
if (map_wayPoints[i].x < 0 ||
|
||||||
|
map_wayPoints[i].x > 25 ||
|
||||||
|
map_wayPoints[i].y < 0 || map_wayPoints[i].y > 27)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tmp = ABS(map_curGoblinX - map_wayPoints[i].x) +
|
||||||
|
ABS(map_curGoblinY - map_wayPoints[i].y);
|
||||||
|
|
||||||
|
if (tmp <= length) {
|
||||||
|
map_nearestWayPoint = i;
|
||||||
|
length = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_findNearestToDest(void) {
|
||||||
|
int16 length;
|
||||||
|
int16 tmp;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
length = 30000;
|
||||||
|
for (i = 0; i < 40; i++) {
|
||||||
|
if (map_wayPoints[i].x < 0 ||
|
||||||
|
map_wayPoints[i].x > 25 ||
|
||||||
|
map_wayPoints[i].y < 0 || map_wayPoints[i].y > 27)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tmp = ABS(map_destX - map_wayPoints[i].x) +
|
||||||
|
ABS(map_destY - map_wayPoints[i].y);
|
||||||
|
|
||||||
|
if (tmp <= length) {
|
||||||
|
map_nearestDest = i;
|
||||||
|
length = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 map_checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1) {
|
||||||
|
uint16 dir;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
dir = map_getDirection(x0, y0, x1, y1);
|
||||||
|
|
||||||
|
if (x0 == x1 && y0 == y1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (dir == 0)
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case 0x4700:
|
||||||
|
x0--;
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4800:
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4900:
|
||||||
|
x0++;
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4b00:
|
||||||
|
x0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4d00:
|
||||||
|
x0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4f00:
|
||||||
|
x0--;
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5000:
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5100:
|
||||||
|
x0++;
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 map_checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1) {
|
||||||
|
uint16 dir;
|
||||||
|
int16 curX;
|
||||||
|
int16 curY;
|
||||||
|
int16 nextLink;
|
||||||
|
|
||||||
|
curX = x0;
|
||||||
|
curY = y0;
|
||||||
|
dir = 0;
|
||||||
|
|
||||||
|
nextLink = 1;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (x0 == curX && y0 == curY)
|
||||||
|
nextLink = 1;
|
||||||
|
|
||||||
|
if (nextLink != 0) {
|
||||||
|
if (map_checkDirectPath(x0, y0, x1, y1) == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
nextLink = 0;
|
||||||
|
if (i0 > i1) {
|
||||||
|
curX = map_wayPoints[i0].x;
|
||||||
|
curY = map_wayPoints[i0].y;
|
||||||
|
i0--;
|
||||||
|
} else if (i0 < i1) {
|
||||||
|
curX = map_wayPoints[i0].x;
|
||||||
|
curY = map_wayPoints[i0].y;
|
||||||
|
i0++;
|
||||||
|
} else if (i0 == i1) {
|
||||||
|
curX = map_wayPoints[i0].x;
|
||||||
|
curY = map_wayPoints[i0].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i0 == i1 && map_wayPoints[i0].x == x0
|
||||||
|
&& map_wayPoints[i0].y == y0) {
|
||||||
|
if (map_checkDirectPath(x0, y0, x1, y1) == 1)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dir = map_getDirection(x0, y0, curX, curY);
|
||||||
|
switch (dir) {
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 0x4700:
|
||||||
|
x0--;
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4800:
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4900:
|
||||||
|
x0++;
|
||||||
|
y0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4b00:
|
||||||
|
x0--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4d00:
|
||||||
|
x0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4f00:
|
||||||
|
x0--;
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5000:
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5100:
|
||||||
|
x0++;
|
||||||
|
y0++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 map_optimizePoints(int16 xPos, int16 yPos) {
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (map_nearestWayPoint < map_nearestDest) {
|
||||||
|
for (i = map_nearestWayPoint; i <= map_nearestDest; i++) {
|
||||||
|
if (map_checkDirectPath(xPos, yPos,
|
||||||
|
map_wayPoints[i].x, map_wayPoints[i].y) == 1)
|
||||||
|
map_nearestWayPoint = i;
|
||||||
|
}
|
||||||
|
} else if (map_nearestWayPoint > map_nearestDest) {
|
||||||
|
for (i = map_nearestWayPoint; i >= map_nearestDest; i--) {
|
||||||
|
if (map_checkDirectPath(xPos, yPos,
|
||||||
|
map_wayPoints[i].x, map_wayPoints[i].y) == 1)
|
||||||
|
map_nearestWayPoint = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map_nearestWayPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_loadDataFromAvo(char *dest, int16 size) {
|
||||||
|
memcpy(dest, map_avoDataPtr, size);
|
||||||
|
map_avoDataPtr += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_loadItemToObject(void) {
|
||||||
|
int16 flag;
|
||||||
|
int16 count;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&flag, 2);
|
||||||
|
flag = FROM_LE_16(flag);
|
||||||
|
if (flag == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
map_avoDataPtr += 1456;
|
||||||
|
map_loadDataFromAvo((char *)&count, 2);
|
||||||
|
count = FROM_LE_16(count);
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
map_avoDataPtr += 20;
|
||||||
|
map_loadDataFromAvo((char *)(&gob_itemToObject[i]), 2);
|
||||||
|
gob_itemToObject[i] = FROM_LE_16(gob_itemToObject[i]);
|
||||||
|
map_avoDataPtr += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_loadMapObjects(char *avjFile) {
|
||||||
|
int16 i;
|
||||||
|
char avoName[128];
|
||||||
|
int16 handle;
|
||||||
|
char item;
|
||||||
|
int16 soundCount;
|
||||||
|
int16 tmp;
|
||||||
|
char *savedPtr;
|
||||||
|
char *savedPtr2;
|
||||||
|
char *savedPtr3;
|
||||||
|
int16 state;
|
||||||
|
int16 col;
|
||||||
|
int32 flag;
|
||||||
|
Gob_State *pState;
|
||||||
|
char buf[128];
|
||||||
|
char sndNames[20][14];
|
||||||
|
char *dataBuf;
|
||||||
|
int16 x;
|
||||||
|
int16 y;
|
||||||
|
int16 count2;
|
||||||
|
int16 count3;
|
||||||
|
|
||||||
|
strcpy(avoName, map_sourceFile);
|
||||||
|
strcat(avoName, ".avo");
|
||||||
|
|
||||||
|
handle = data_openData(avoName);
|
||||||
|
if (handle >= 0) {
|
||||||
|
map_loadFromAvo = 1;
|
||||||
|
data_closeData(handle);
|
||||||
|
map_avoDataPtr = data_getSmallData(avoName);
|
||||||
|
dataBuf = map_avoDataPtr;
|
||||||
|
map_loadDataFromAvo((char *)map_passMap, 28 * 26);
|
||||||
|
|
||||||
|
for (y = 0; y < 28; y++) {
|
||||||
|
for (x = 0; x < 26; x++) {
|
||||||
|
map_loadDataFromAvo(&item, 1);
|
||||||
|
map_itemsMap[y][x] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 40; i++) {
|
||||||
|
map_loadDataFromAvo((char *)(&map_wayPoints[i].x), 2);
|
||||||
|
map_wayPoints[i].x = FROM_LE_16(map_wayPoints[i].x);
|
||||||
|
map_loadDataFromAvo((char *)(&map_wayPoints[i].y), 2);
|
||||||
|
map_wayPoints[i].y = FROM_LE_16(map_wayPoints[i].y);
|
||||||
|
}
|
||||||
|
map_loadDataFromAvo((char *)map_itemPoses, szMap_ItemPos * 20);
|
||||||
|
} else {
|
||||||
|
map_loadFromAvo = 0;
|
||||||
|
map_avoDataPtr = data_getSmallData(avjFile);
|
||||||
|
dataBuf = map_avoDataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_avoDataPtr += 32;
|
||||||
|
map_avoDataPtr += 76;
|
||||||
|
map_avoDataPtr += 4;
|
||||||
|
map_avoDataPtr += 20;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
map_loadDataFromAvo((char *)&tmp, 2);
|
||||||
|
tmp = FROM_LE_16(tmp);
|
||||||
|
map_avoDataPtr += tmp * 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&soundCount, 2);
|
||||||
|
soundCount = FROM_LE_16(soundCount);
|
||||||
|
savedPtr = map_avoDataPtr;
|
||||||
|
|
||||||
|
map_avoDataPtr += 14 * soundCount;
|
||||||
|
map_avoDataPtr += 4;
|
||||||
|
map_avoDataPtr += 24;
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&count2, 2);
|
||||||
|
count2 = FROM_LE_16(count2);
|
||||||
|
map_loadDataFromAvo((char *)&count3, 2);
|
||||||
|
count3 = FROM_LE_16(count3);
|
||||||
|
|
||||||
|
savedPtr2 = map_avoDataPtr;
|
||||||
|
map_avoDataPtr += count2 * 8;
|
||||||
|
|
||||||
|
savedPtr3 = map_avoDataPtr;
|
||||||
|
map_avoDataPtr += count3 * 8;
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&gob_gobsCount, 2);
|
||||||
|
gob_gobsCount = FROM_LE_16(gob_gobsCount);
|
||||||
|
for (i = 0; i < gob_gobsCount; i++) {
|
||||||
|
gob_goblins[i] = (Gob_Object *)malloc(sizeof(Gob_Object));
|
||||||
|
|
||||||
|
gob_goblins[i]->xPos = READ_LE_UINT16(savedPtr2);
|
||||||
|
savedPtr2 += 2;
|
||||||
|
|
||||||
|
gob_goblins[i]->yPos = READ_LE_UINT16(savedPtr2);
|
||||||
|
savedPtr2 += 2;
|
||||||
|
|
||||||
|
gob_goblins[i]->order = READ_LE_UINT16(savedPtr2);
|
||||||
|
savedPtr2 += 2;
|
||||||
|
|
||||||
|
gob_goblins[i]->state = READ_LE_UINT16(savedPtr2);
|
||||||
|
savedPtr2 += 2;
|
||||||
|
|
||||||
|
if (i == 3)
|
||||||
|
gob_goblins[i]->stateMach = (Gob_StateLine *)malloc(sizeof(Gob_StateLine) * 70);
|
||||||
|
else
|
||||||
|
gob_goblins[i]->stateMach = (Gob_StateLine *)malloc(sizeof(Gob_StateLine) * 40);
|
||||||
|
|
||||||
|
// FIXME: All is wrong further. We should unwind calls to map_loadDataFromAvo()
|
||||||
|
map_loadDataFromAvo((char *)gob_goblins[i]->stateMach, 40 * szGob_StateLine);
|
||||||
|
map_avoDataPtr += 160;
|
||||||
|
gob_goblins[i]->multObjIndex = *map_avoDataPtr;
|
||||||
|
map_avoDataPtr += 2;
|
||||||
|
|
||||||
|
gob_goblins[i]->realStateMach = gob_goblins[i]->stateMach;
|
||||||
|
|
||||||
|
for (state = 0; state < 40; state++) {
|
||||||
|
for (col = 0; col < 6; col++) {
|
||||||
|
if (gob_goblins[i]->stateMach[state][col] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gob_goblins[i]->stateMach[state][col] = (Gob_State *)malloc(sizeof(Gob_State));
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)gob_goblins[i]->stateMach[state][col], 4);
|
||||||
|
map_avoDataPtr += 8;
|
||||||
|
map_loadDataFromAvo(((char *)gob_goblins[i]->stateMach[state][col]) + 4, 4);
|
||||||
|
|
||||||
|
map_avoDataPtr += 2;
|
||||||
|
if (READ_LE_UINT32(map_avoDataPtr) != 0) {
|
||||||
|
map_avoDataPtr += 4;
|
||||||
|
map_loadDataFromAvo((char
|
||||||
|
*)(&gob_goblins[i]->
|
||||||
|
stateMach[state][col]->
|
||||||
|
sndItem), 2);
|
||||||
|
} else {
|
||||||
|
map_avoDataPtr += 6;
|
||||||
|
gob_goblins[i]->stateMach[state][col]->
|
||||||
|
sndItem = -1;
|
||||||
|
}
|
||||||
|
map_loadDataFromAvo((char *)(&gob_goblins[i]->
|
||||||
|
stateMach[state][col]->freq), 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
||||||
|
gob_goblins[0]->stateMach[39][0] = pState;
|
||||||
|
pState->animation = 0;
|
||||||
|
pState->layer = 98;
|
||||||
|
pState->unk0 = 0;
|
||||||
|
pState->unk1 = 0;
|
||||||
|
pState->sndItem = -1;
|
||||||
|
|
||||||
|
pState = (Gob_State *) malloc(sizeof(Gob_State));
|
||||||
|
gob_goblins[1]->stateMach[39][0] = pState;
|
||||||
|
pState->animation = 0;
|
||||||
|
pState->layer = 99;
|
||||||
|
pState->unk0 = 0;
|
||||||
|
pState->unk1 = 0;
|
||||||
|
pState->sndItem = -1;
|
||||||
|
|
||||||
|
pState = (Gob_State *) malloc(sizeof(Gob_State));
|
||||||
|
gob_goblins[2]->stateMach[39][0] = pState;
|
||||||
|
pState->animation = 0;
|
||||||
|
pState->layer = 100;
|
||||||
|
pState->unk0 = 0;
|
||||||
|
pState->unk1 = 0;
|
||||||
|
pState->sndItem = -1;
|
||||||
|
|
||||||
|
gob_goblins[2]->stateMach[10][0]->unk2 = 13;
|
||||||
|
gob_goblins[2]->stateMach[11][0]->unk2 = 13;
|
||||||
|
gob_goblins[2]->stateMach[28][0]->unk2 = 13;
|
||||||
|
gob_goblins[2]->stateMach[29][0]->unk2 = 13;
|
||||||
|
|
||||||
|
gob_goblins[1]->stateMach[10][0]->unk2 = 13;
|
||||||
|
gob_goblins[1]->stateMach[11][0]->unk2 = 13;
|
||||||
|
|
||||||
|
for (state = 40; state < 70; state++) {
|
||||||
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
||||||
|
gob_goblins[3]->stateMach[state][0] = pState;
|
||||||
|
gob_goblins[3]->stateMach[state][1] = 0;
|
||||||
|
|
||||||
|
pState->animation = 9;
|
||||||
|
pState->layer = state - 40;
|
||||||
|
pState->sndItem = -1;
|
||||||
|
pState->unk2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&gob_objCount, 2);
|
||||||
|
for (i = 0; i < gob_objCount; i++) {
|
||||||
|
gob_objects[i] =
|
||||||
|
(Gob_Object *) malloc(sizeof(Gob_Object));
|
||||||
|
|
||||||
|
gob_objects[i]->xPos = READ_LE_UINT16(savedPtr3);
|
||||||
|
savedPtr3 += 2;
|
||||||
|
|
||||||
|
gob_objects[i]->yPos = READ_LE_UINT16(savedPtr3);
|
||||||
|
savedPtr3 += 2;
|
||||||
|
|
||||||
|
gob_objects[i]->order = READ_LE_UINT16(savedPtr3);
|
||||||
|
savedPtr3 += 2;
|
||||||
|
|
||||||
|
gob_objects[i]->state = READ_LE_UINT16(savedPtr3);
|
||||||
|
savedPtr3 += 2;
|
||||||
|
|
||||||
|
gob_objects[i]->stateMach = (Gob_StateLine *)malloc(sizeof(Gob_StateLine) * 40);
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)gob_objects[i]->stateMach, 40 * szGob_StateLine);
|
||||||
|
map_avoDataPtr += 160;
|
||||||
|
gob_objects[i]->multObjIndex = *map_avoDataPtr;
|
||||||
|
map_avoDataPtr += 2;
|
||||||
|
|
||||||
|
gob_objects[i]->realStateMach = gob_objects[i]->stateMach;
|
||||||
|
for (state = 0; state < 40; state++) {
|
||||||
|
for (col = 0; col < 6; col++) {
|
||||||
|
if (gob_objects[i]->stateMach[state][col] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gob_objects[i]->stateMach[state][col] = (Gob_State *)malloc(sizeof(Gob_State));
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)gob_objects[i]->stateMach[state][col], 4);
|
||||||
|
map_avoDataPtr += 8;
|
||||||
|
map_loadDataFromAvo(((char *)gob_objects[i]->stateMach[state][col]) + 4, 4);
|
||||||
|
|
||||||
|
map_avoDataPtr += 2;
|
||||||
|
if (READ_LE_UINT32(map_avoDataPtr) != 0) {
|
||||||
|
map_avoDataPtr += 4;
|
||||||
|
map_loadDataFromAvo((char *)(&gob_objects[i]->stateMach[state][col]->sndItem), 2);
|
||||||
|
} else {
|
||||||
|
map_avoDataPtr += 6;
|
||||||
|
gob_objects[i]->stateMach[state][col]->sndItem = -1;
|
||||||
|
}
|
||||||
|
map_loadDataFromAvo((char *)(&gob_objects[i]->stateMach[state][col]->freq), 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gob_objects[10] = (Gob_Object *)malloc(sizeof(Gob_Object));
|
||||||
|
memset(gob_objects[10], 0, sizeof(Gob_Object));
|
||||||
|
|
||||||
|
gob_objects[10]->stateMach = (Gob_StateLine *)malloc(sizeof(Gob_StateLine) * 40);
|
||||||
|
memset(gob_objects[10]->stateMach, 0, sizeof(Gob_StateLine) * 40);
|
||||||
|
|
||||||
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
||||||
|
gob_objects[10]->stateMach[0][0] = pState;
|
||||||
|
|
||||||
|
memset(pState, 0, sizeof(Gob_State));
|
||||||
|
pState->animation = 9;
|
||||||
|
pState->layer = 27;
|
||||||
|
pState->unk0 = 0;
|
||||||
|
pState->unk1 = 0;
|
||||||
|
pState->sndItem = -1;
|
||||||
|
pState->unk2 = 0;
|
||||||
|
|
||||||
|
gob_placeObject(gob_objects[10], 1);
|
||||||
|
|
||||||
|
gob_objects[10]->realStateMach = gob_objects[10]->stateMach;
|
||||||
|
gob_objects[10]->type = 1;
|
||||||
|
gob_objects[10]->unk14 = 1;
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&state, 2);
|
||||||
|
for (i = 0; i < state; i++) {
|
||||||
|
map_avoDataPtr += 30;
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&flag, 4);
|
||||||
|
map_avoDataPtr += 56;
|
||||||
|
|
||||||
|
if (flag != 0)
|
||||||
|
map_avoDataPtr += 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_loadDataFromAvo((char *)&tmp, 2);
|
||||||
|
map_avoDataPtr += 48;
|
||||||
|
map_loadItemToObject();
|
||||||
|
map_avoDataPtr = savedPtr;
|
||||||
|
|
||||||
|
for (i = 0; i < soundCount; i++) {
|
||||||
|
map_loadDataFromAvo(buf, 14);
|
||||||
|
strcat(buf, ".SND");
|
||||||
|
strcpy(sndNames[i], buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dataBuf);
|
||||||
|
|
||||||
|
gob_soundData[14] = snd_loadSoundData("diamant1.snd");
|
||||||
|
|
||||||
|
for (i = 0; i < soundCount; i++) {
|
||||||
|
handle = data_openData(sndNames[i]);
|
||||||
|
if (handle < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
data_closeData(handle);
|
||||||
|
gob_soundData[i] = snd_loadSoundData(sndNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_loadMapsInitGobs(void) {
|
||||||
|
int16 layer;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (map_loadFromAvo == 0)
|
||||||
|
error("map_load: Loading .pas/.pos files is not supported!");
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
gob_nextLayer(gob_goblins[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
|
||||||
|
layer =
|
||||||
|
gob_goblins[i]->stateMach[gob_goblins[i]->state][0]->layer;
|
||||||
|
|
||||||
|
scen_updateAnim(layer, 0, gob_goblins[i]->animation, 0,
|
||||||
|
gob_goblins[i]->xPos, gob_goblins[i]->yPos, 0);
|
||||||
|
|
||||||
|
gob_goblins[i]->yPos = (gob_gobPositions[i].y + 1) * 6 -
|
||||||
|
(scen_toRedrawBottom - scen_animTop);
|
||||||
|
|
||||||
|
gob_goblins[i]->xPos = gob_gobPositions[i].x * 12 -
|
||||||
|
(scen_toRedrawLeft - scen_animLeft);
|
||||||
|
|
||||||
|
gob_goblins[i]->order = scen_toRedrawBottom / 24 + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
gob_currentGoblin = 0;
|
||||||
|
gob_pressedMapX = gob_gobPositions[0].x;
|
||||||
|
gob_pressedMapY = gob_gobPositions[0].y;
|
||||||
|
gob_pathExistence = 0;
|
||||||
|
|
||||||
|
gob_goblins[0]->doAnim = 0;
|
||||||
|
gob_goblins[1]->doAnim = 1;
|
||||||
|
gob_goblins[2]->doAnim = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
57
gob/map.h
Normal file
57
gob/map.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __MAP_H
|
||||||
|
#define __MAP_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#pragma START_PACK_STRUCTS
|
||||||
|
#define szMap_Point 4
|
||||||
|
typedef struct Map_Point {
|
||||||
|
int16 x;
|
||||||
|
int16 y;
|
||||||
|
} GCC_PACK Map_Point;
|
||||||
|
|
||||||
|
#define szMap_ItemPos 3
|
||||||
|
typedef struct Map_ItemPos {
|
||||||
|
char x;
|
||||||
|
char y;
|
||||||
|
char orient; // ??
|
||||||
|
} GCC_PACK Map_ItemPos;
|
||||||
|
#pragma END_PACK_STRUCTS
|
||||||
|
|
||||||
|
extern char map_passMap[28][26]; // [y][x]
|
||||||
|
extern int16 map_itemsMap[28][26]; // [y][x]
|
||||||
|
extern Map_Point map_wayPoints[40];
|
||||||
|
extern int16 map_nearestWayPoint;
|
||||||
|
extern int16 map_nearestDest;
|
||||||
|
|
||||||
|
extern int16 map_curGoblinX;
|
||||||
|
extern int16 map_curGoblinY;
|
||||||
|
extern int16 map_destX;
|
||||||
|
extern int16 map_destY;
|
||||||
|
extern char map_loadFromAvo;
|
||||||
|
|
||||||
|
extern Map_ItemPos map_itemPoses[40];
|
||||||
|
extern char map_sourceFile[15];
|
||||||
|
extern char *map_avoDataPtr;
|
||||||
|
|
||||||
|
int16 map_getDirection(int16 x0, int16 y0, int16 x1, int16 y1);
|
||||||
|
void map_findNearestToGob(void);
|
||||||
|
void map_findNearestToDest(void);
|
||||||
|
int16 map_checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1);
|
||||||
|
int16 map_checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
|
||||||
|
int16 map_optimizePoints(int16 xPos, int16 yPos);
|
||||||
|
void map_loadItemToObject(void);
|
||||||
|
void map_loadMapObjects(char *avjFile);
|
||||||
|
void map_loadDataFromAvo(char *dest, int16 size);
|
||||||
|
void map_loadMapsInitGobs(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __MAP_H */
|
36
gob/module.mk
Normal file
36
gob/module.mk
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
MODULE := gob
|
||||||
|
|
||||||
|
MODULE_OBJS := \
|
||||||
|
gob/anim.o \
|
||||||
|
gob/dataio.o \
|
||||||
|
gob/debug.o \
|
||||||
|
gob/draw.o \
|
||||||
|
gob/driver_vga.o \
|
||||||
|
gob/game.o \
|
||||||
|
gob/global.o \
|
||||||
|
gob/goblin.o \
|
||||||
|
gob/init.o \
|
||||||
|
gob/inter.o \
|
||||||
|
gob/map.o \
|
||||||
|
gob/mult.o \
|
||||||
|
gob/pack.o \
|
||||||
|
gob/palanim.o \
|
||||||
|
gob/parse.o \
|
||||||
|
gob/resource.o \
|
||||||
|
gob/scenery.o \
|
||||||
|
gob/util.o \
|
||||||
|
gob/video.o \
|
||||||
|
gob/sound.o \
|
||||||
|
gob/timer.o \
|
||||||
|
gob/gob.o
|
||||||
|
|
||||||
|
MODULE_DIRS += \
|
||||||
|
gob
|
||||||
|
|
||||||
|
# This module can be built as a plugin
|
||||||
|
ifdef BUILD_PLUGINS
|
||||||
|
PLUGIN := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Include common rules
|
||||||
|
include $(srcdir)/common.rules
|
1205
gob/mult.cpp
Normal file
1205
gob/mult.cpp
Normal file
File diff suppressed because it is too large
Load diff
185
gob/mult.h
Normal file
185
gob/mult.h
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __MULT_H
|
||||||
|
#define __MULT_H
|
||||||
|
|
||||||
|
#include "gob/sound.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#pragma START_PACK_STRUCTS
|
||||||
|
typedef struct Mult_AnimData {
|
||||||
|
char animation;
|
||||||
|
char layer;
|
||||||
|
char frame;
|
||||||
|
char animType;
|
||||||
|
char order;
|
||||||
|
char isPaused;
|
||||||
|
char isStatic;
|
||||||
|
char maxTick;
|
||||||
|
char unknown;
|
||||||
|
char newLayer;
|
||||||
|
char newAnimation;
|
||||||
|
byte intersected;
|
||||||
|
char newCycle;
|
||||||
|
} GCC_PACK Mult_AnimData;
|
||||||
|
|
||||||
|
typedef struct Mult_Object {
|
||||||
|
int32 *pPosX;
|
||||||
|
int32 *pPosY;
|
||||||
|
Mult_AnimData *pAnimData;
|
||||||
|
int16 tick;
|
||||||
|
int16 lastLeft;
|
||||||
|
int16 lastRight;
|
||||||
|
int16 lastTop;
|
||||||
|
int16 lastBottom;
|
||||||
|
} Mult_Object;
|
||||||
|
|
||||||
|
// Mult
|
||||||
|
typedef struct Mult_StaticKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 layer;
|
||||||
|
} GCC_PACK Mult_StaticKey;
|
||||||
|
|
||||||
|
typedef struct Mult_AnimKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 layer;
|
||||||
|
int16 posX;
|
||||||
|
int16 posY;
|
||||||
|
int16 order;
|
||||||
|
} GCC_PACK Mult_AnimKey;
|
||||||
|
|
||||||
|
typedef struct Mult_TextKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 cmd;
|
||||||
|
int16 unknown0[9];
|
||||||
|
int16 index;
|
||||||
|
int16 unknown1[2];
|
||||||
|
} GCC_PACK Mult_TextKey;
|
||||||
|
|
||||||
|
typedef struct Mult_PalKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 cmd;
|
||||||
|
int16 rates[4];
|
||||||
|
int16 unknown0;
|
||||||
|
int16 unknown1;
|
||||||
|
char subst[16][4];
|
||||||
|
} GCC_PACK Mult_PalKey;
|
||||||
|
|
||||||
|
typedef struct Mult_PalFadeKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 fade;
|
||||||
|
int16 palIndex;
|
||||||
|
char flag;
|
||||||
|
} GCC_PACK Mult_PalFadeKey;
|
||||||
|
|
||||||
|
typedef struct Mult_SndKey {
|
||||||
|
int16 frame;
|
||||||
|
int16 cmd;
|
||||||
|
int16 freq;
|
||||||
|
int16 channel;
|
||||||
|
int16 repCount;
|
||||||
|
int16 resId;
|
||||||
|
int16 soundIndex;
|
||||||
|
} GCC_PACK Mult_SndKey;
|
||||||
|
#pragma END_PACK_STRUCTS
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
extern Mult_Object *mult_objects;
|
||||||
|
extern int16 *mult_renderData;
|
||||||
|
extern int16 mult_objCount;
|
||||||
|
extern SurfaceDesc *mult_underAnimSurf;
|
||||||
|
|
||||||
|
extern char *mult_multData;
|
||||||
|
extern int16 mult_frame;
|
||||||
|
extern char mult_doPalSubst;
|
||||||
|
extern int16 mult_counter;
|
||||||
|
extern int16 mult_frameRate;
|
||||||
|
|
||||||
|
extern int32 *mult_animArrayX;
|
||||||
|
extern int32 *mult_animArrayY;
|
||||||
|
|
||||||
|
extern Mult_AnimData *mult_animArrayData;
|
||||||
|
|
||||||
|
extern int16 mult_index;
|
||||||
|
|
||||||
|
// Static keys
|
||||||
|
extern int16 mult_staticKeysCount;
|
||||||
|
extern Mult_StaticKey *mult_staticKeys;
|
||||||
|
extern int16 mult_staticIndices[10];
|
||||||
|
|
||||||
|
// Anim keys
|
||||||
|
extern Mult_AnimKey *mult_animKeys[4];
|
||||||
|
extern int16 mult_animKeysCount[4];
|
||||||
|
extern int16 mult_animLayer;
|
||||||
|
extern int16 mult_animIndices[10];
|
||||||
|
|
||||||
|
// Text keys
|
||||||
|
extern int16 mult_textKeysCount;
|
||||||
|
extern Mult_TextKey *mult_textKeys;
|
||||||
|
|
||||||
|
extern int16 mult_frameStart;
|
||||||
|
|
||||||
|
// Palette keys
|
||||||
|
extern int16 mult_palKeyIndex;
|
||||||
|
extern int16 mult_palKeysCount;
|
||||||
|
extern Mult_PalKey *mult_palKeys;
|
||||||
|
extern Color *mult_oldPalette;
|
||||||
|
extern Color mult_palAnimPalette[256];
|
||||||
|
extern int16 mult_palAnimKey;
|
||||||
|
extern int16 mult_palAnimIndices[4];
|
||||||
|
extern int16 mult_palAnimRed[4];
|
||||||
|
extern int16 mult_palAnimGreen[4];
|
||||||
|
extern int16 mult_palAnimBlue[4];
|
||||||
|
|
||||||
|
// Palette fading
|
||||||
|
extern Mult_PalFadeKey *mult_palFadeKeys;
|
||||||
|
extern int16 mult_palFadeKeysCount;
|
||||||
|
extern char mult_palFadingRed;
|
||||||
|
extern char mult_palFadingGreen;
|
||||||
|
extern char mult_palFadingBlue;
|
||||||
|
|
||||||
|
extern char mult_animDataAllocated;
|
||||||
|
|
||||||
|
extern char *mult_dataPtr;
|
||||||
|
extern int16 mult_staticLoaded[10];
|
||||||
|
extern int16 mult_animLoaded[10];
|
||||||
|
extern int16 mult_sndSlotsCount;
|
||||||
|
|
||||||
|
// Sound keys
|
||||||
|
extern int16 mult_sndKeysCount;
|
||||||
|
extern Mult_SndKey *mult_sndKeys;
|
||||||
|
|
||||||
|
void mult_playSound(Snd_SoundDesc * soundDesc, int16 repCount, int16 freq,
|
||||||
|
int16 negFreq);
|
||||||
|
void mult_zeroMultData(void);
|
||||||
|
void mult_loadMult(int16 resId);
|
||||||
|
void mult_freeMultKeys(void);
|
||||||
|
void mult_checkFreeMult(void);
|
||||||
|
void mult_playMult(int16 startFrame, int16 endFrame, char checkEscape,
|
||||||
|
char handleMouse);
|
||||||
|
void mult_animate(void);
|
||||||
|
void mult_interGetObjAnimSize(void);
|
||||||
|
void mult_interInitMult(void);
|
||||||
|
void mult_freeMult(void);
|
||||||
|
void mult_interLoadMult(void);
|
||||||
|
void mult_freeAll(void);
|
||||||
|
void mult_initAll(void);
|
||||||
|
void mult_playSound(Snd_SoundDesc * soundDesc, int16 repCount, int16 freq,
|
||||||
|
int16 negFreq);
|
||||||
|
void mult_playMult(int16 startFrame, int16 endFrame, char checkEscape,
|
||||||
|
char handleMouse);
|
||||||
|
void mult_zeroMultData(void);
|
||||||
|
void mult_loadMult(int16 resId);
|
||||||
|
void mult_freeMultKeys(void);
|
||||||
|
void mult_checkFreeMult(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __MULT_H */
|
94
gob/pack.cpp
Normal file
94
gob/pack.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/pack.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int32 unpackData(char *sourceBuf, char *destBuf) {
|
||||||
|
uint32 realSize;
|
||||||
|
uint32 counter;
|
||||||
|
uint16 cmd;
|
||||||
|
byte *src;
|
||||||
|
byte *dest;
|
||||||
|
byte *tmpBuf;
|
||||||
|
int16 off;
|
||||||
|
byte len;
|
||||||
|
byte i;
|
||||||
|
int16 j;
|
||||||
|
uint16 tmpIndex;
|
||||||
|
|
||||||
|
realSize = READ_LE_UINT32(sourceBuf);
|
||||||
|
counter = READ_LE_UINT32(sourceBuf);
|
||||||
|
|
||||||
|
tmpBuf = (byte *)malloc(4114);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can use assembler unpacker for small blocks - for speed.
|
||||||
|
* Don't need this anymore :)
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* if(realSize < 65000)
|
||||||
|
* {
|
||||||
|
* asm_unpackData(sourceBuf, destBuf, tmpBuf);
|
||||||
|
* free(tmpBuf);
|
||||||
|
* return realSize;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (tmpBuf == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (j = 0; j < 4078; j++)
|
||||||
|
tmpBuf[j] = 0x20;
|
||||||
|
tmpIndex = 4078;
|
||||||
|
|
||||||
|
src = (byte *)(sourceBuf + 4);
|
||||||
|
dest = (byte *)destBuf;
|
||||||
|
|
||||||
|
cmd = 0;
|
||||||
|
while (1) {
|
||||||
|
cmd >>= 1;
|
||||||
|
if ((cmd & 0x0100) == 0) {
|
||||||
|
cmd = *src | 0xff00;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
if ((cmd & 1) != 0) { /* copy */
|
||||||
|
*dest++ = *src;
|
||||||
|
tmpBuf[tmpIndex] = *src;
|
||||||
|
src++;
|
||||||
|
tmpIndex++;
|
||||||
|
tmpIndex %= 4096;
|
||||||
|
counter--;
|
||||||
|
if (counter == 0)
|
||||||
|
break;
|
||||||
|
} else { /* copy string */
|
||||||
|
|
||||||
|
off = *src++;
|
||||||
|
off |= (*src & 0xf0) << 4;
|
||||||
|
len = (*src & 0x0f) + 3;
|
||||||
|
src++;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*dest++ = tmpBuf[(off + i) % 4096];
|
||||||
|
counter--;
|
||||||
|
if (counter == 0) {
|
||||||
|
free(tmpBuf);
|
||||||
|
return realSize;
|
||||||
|
}
|
||||||
|
tmpBuf[tmpIndex] = tmpBuf[(off + i) % 4096];
|
||||||
|
tmpIndex++;
|
||||||
|
tmpIndex %= 4096;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tmpBuf);
|
||||||
|
return realSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
18
gob/pack.h
Normal file
18
gob/pack.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __UNPACKER_H
|
||||||
|
#define __UNPACKER_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int32 asm_unpackData(char *source, char *dest, char *temp);
|
||||||
|
int32 unpackData(char *source, char *dest);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
224
gob/palanim.cpp
Normal file
224
gob/palanim.cpp
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/palanim.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 pal_fadeValue = 1;
|
||||||
|
|
||||||
|
char pal_toFadeRed[256];
|
||||||
|
char pal_toFadeGreen[256];
|
||||||
|
char pal_toFadeBlue[256];
|
||||||
|
|
||||||
|
char pal_fadeColor(char from, char to) {
|
||||||
|
if ((int16)from - pal_fadeValue > (int16)to)
|
||||||
|
return from - pal_fadeValue;
|
||||||
|
else if ((int16)from + pal_fadeValue < (int16)to)
|
||||||
|
return from + pal_fadeValue;
|
||||||
|
else
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
char pal_fadeStep(int16 oper) {
|
||||||
|
char newRed;
|
||||||
|
char newGreen;
|
||||||
|
char newBlue;
|
||||||
|
char stop;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (colorCount != 256)
|
||||||
|
error("pal_fadeStep: Only 256 color mode is supported!");
|
||||||
|
|
||||||
|
if (oper == 0) {
|
||||||
|
stop = 1;
|
||||||
|
if (setAllPalette) {
|
||||||
|
if (inVM != 0)
|
||||||
|
error("pal_fade: inVM != 0 not supported.");
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
newRed =
|
||||||
|
pal_fadeColor(redPalette[i],
|
||||||
|
pal_toFadeRed[i]);
|
||||||
|
newGreen =
|
||||||
|
pal_fadeColor(greenPalette[i],
|
||||||
|
pal_toFadeGreen[i]);
|
||||||
|
newBlue =
|
||||||
|
pal_fadeColor(bluePalette[i],
|
||||||
|
pal_toFadeBlue[i]);
|
||||||
|
|
||||||
|
if (redPalette[i] != newRed
|
||||||
|
|| greenPalette[i] != newGreen
|
||||||
|
|| bluePalette[i] != newBlue) {
|
||||||
|
|
||||||
|
vid_setPalElem(i, newRed, newGreen, newBlue, 0, 0x13);
|
||||||
|
|
||||||
|
redPalette[i] = newRed;
|
||||||
|
greenPalette[i] = newGreen;
|
||||||
|
bluePalette[i] = newBlue;
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
|
||||||
|
vid_setPalElem(i,
|
||||||
|
pal_fadeColor(redPalette[i],
|
||||||
|
pal_toFadeRed[i]),
|
||||||
|
pal_fadeColor(greenPalette[i],
|
||||||
|
pal_toFadeGreen[i]),
|
||||||
|
pal_fadeColor(bluePalette[i],
|
||||||
|
pal_toFadeBlue[i]), -1, videoMode);
|
||||||
|
|
||||||
|
if (redPalette[i] != pal_toFadeRed[i] ||
|
||||||
|
greenPalette[i] != pal_toFadeGreen[i] ||
|
||||||
|
bluePalette[i] != pal_toFadeBlue[i])
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stop;
|
||||||
|
} else if (oper == 1) {
|
||||||
|
stop = 1;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
vid_setPalElem(i,
|
||||||
|
pal_fadeColor(redPalette[i], pal_toFadeRed[i]),
|
||||||
|
greenPalette[i], bluePalette[i], -1, videoMode);
|
||||||
|
|
||||||
|
if (redPalette[i] != pal_toFadeRed[i])
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
|
return stop;
|
||||||
|
} else if (oper == 2) {
|
||||||
|
stop = 1;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
vid_setPalElem(i,
|
||||||
|
redPalette[i],
|
||||||
|
pal_fadeColor(greenPalette[i], pal_toFadeGreen[i]),
|
||||||
|
bluePalette[i], -1, videoMode);
|
||||||
|
|
||||||
|
if (greenPalette[i] != pal_toFadeGreen[i])
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
|
return stop;
|
||||||
|
} else if (oper == 3) {
|
||||||
|
stop = 1;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
vid_setPalElem(i,
|
||||||
|
redPalette[i],
|
||||||
|
greenPalette[i],
|
||||||
|
pal_fadeColor(bluePalette[i], pal_toFadeBlue[i]),
|
||||||
|
-1, videoMode);
|
||||||
|
|
||||||
|
if (bluePalette[i] != pal_toFadeBlue[i])
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
|
return stop;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pal_fade(PalDesc * palDesc, int16 fade, int16 allColors) {
|
||||||
|
char stop;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
if (fade < 0)
|
||||||
|
pal_fadeValue = -fade;
|
||||||
|
else
|
||||||
|
pal_fadeValue = 2;
|
||||||
|
|
||||||
|
if (colorCount < 256) {
|
||||||
|
if (palDesc != 0)
|
||||||
|
vid_setFullPalette(palDesc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setAllPalette == 0) {
|
||||||
|
if (palDesc == 0) {
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
pal_toFadeRed[i] = 0;
|
||||||
|
pal_toFadeGreen[i] = 0;
|
||||||
|
pal_toFadeBlue[i] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
pal_toFadeRed[i] = palDesc->vgaPal[i].red;
|
||||||
|
pal_toFadeGreen[i] = palDesc->vgaPal[i].green;
|
||||||
|
pal_toFadeBlue[i] = palDesc->vgaPal[i].blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (inVM != 0)
|
||||||
|
error("pal_fade: inVM != 0 is not supported");
|
||||||
|
|
||||||
|
if (palDesc == 0) {
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
pal_toFadeRed[i] = 0;
|
||||||
|
pal_toFadeGreen[i] = 0;
|
||||||
|
pal_toFadeBlue[i] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
pal_toFadeRed[i] = palDesc->vgaPal[i].red;
|
||||||
|
pal_toFadeGreen[i] = palDesc->vgaPal[i].green;
|
||||||
|
pal_toFadeBlue[i] = palDesc->vgaPal[i].blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allColors == 0) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (tmpPalBuffer == 0)
|
||||||
|
vid_waitRetrace(videoMode);
|
||||||
|
|
||||||
|
stop = pal_fadeStep(0);
|
||||||
|
|
||||||
|
if (fade > 0)
|
||||||
|
util_delay(fade);
|
||||||
|
} while (stop == 0);
|
||||||
|
|
||||||
|
if (palDesc != 0)
|
||||||
|
vid_setFullPalette(palDesc);
|
||||||
|
else
|
||||||
|
util_clearPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allColors == 1) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
vid_waitRetrace(videoMode);
|
||||||
|
stop = pal_fadeStep(1);
|
||||||
|
} while (stop == 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
vid_waitRetrace(videoMode);
|
||||||
|
stop = pal_fadeStep(2);
|
||||||
|
} while (stop == 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
vid_waitRetrace(videoMode);
|
||||||
|
stop = pal_fadeStep(3);
|
||||||
|
} while (stop == 0);
|
||||||
|
|
||||||
|
if (palDesc != 0)
|
||||||
|
vid_setFullPalette(palDesc);
|
||||||
|
else
|
||||||
|
util_clearPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpPalBuffer != 0) {
|
||||||
|
free((char *)tmpPalBuffer);
|
||||||
|
tmpPalBuffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
21
gob/palanim.h
Normal file
21
gob/palanim.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __PALANIM_H
|
||||||
|
#define __PALANIM_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
extern int16 pal_fadeValue;
|
||||||
|
|
||||||
|
char pal_fadeColor(char from, char to);
|
||||||
|
char pal_fadeStep(int16 oper); // oper == 0 - fade all colors, 1, 2, 3 - red,green, blue
|
||||||
|
void pal_fade(PalDesc * palDesc, int16 fade, int16 all);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __PALANIM_H */
|
1210
gob/parse.cpp
Normal file
1210
gob/parse.cpp
Normal file
File diff suppressed because it is too large
Load diff
22
gob/parse.h
Normal file
22
gob/parse.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __PARSE_H
|
||||||
|
#define __PARSE_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 parse_parseExpr(char stopToken, byte *resultPtr);
|
||||||
|
void parse_skipExpr(char stopToken);
|
||||||
|
int16 parse_parseValExpr(void);
|
||||||
|
int16 parse_parseVarIndex(void);
|
||||||
|
void parse_printExpr(char stopToken);
|
||||||
|
void parse_printVarIndex(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
90
gob/resource.cpp
Normal file
90
gob/resource.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/resource.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
char *resourceBuf = 0;
|
||||||
|
|
||||||
|
static char *resourcePtr;
|
||||||
|
|
||||||
|
void res_Free(void) {
|
||||||
|
if (resourceBuf != 0) {
|
||||||
|
free(resourceBuf);
|
||||||
|
resourceBuf = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void res_Init(void) {
|
||||||
|
int16 handle;
|
||||||
|
int16 fileSize;
|
||||||
|
struct stat statBuf;
|
||||||
|
handle = open("ALL.ASK", O_RDONLY);
|
||||||
|
if (handle < 0) {
|
||||||
|
error("ALL.ASK is missing.");
|
||||||
|
}
|
||||||
|
if (stat("ALL.ASK", &statBuf) == -1)
|
||||||
|
error("res_Init: Error with stat()\n");
|
||||||
|
fileSize = statBuf.st_size;
|
||||||
|
|
||||||
|
resourceBuf = (char *)malloc(fileSize * 4);
|
||||||
|
read(handle, resourceBuf, fileSize);
|
||||||
|
close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void res_Search(char resid) {
|
||||||
|
int16 lang;
|
||||||
|
if (resourceBuf == 0)
|
||||||
|
res_Init();
|
||||||
|
|
||||||
|
lang = (language == 5) ? 2 : language;
|
||||||
|
|
||||||
|
resourcePtr = resourceBuf;
|
||||||
|
while (*resourcePtr != '#') {
|
||||||
|
if (resourcePtr[0] == '@' && resourcePtr[1] == resid &&
|
||||||
|
((int16)lang + '0') == (int16)resourcePtr[2]) {
|
||||||
|
resourcePtr += 5;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
resourcePtr++;
|
||||||
|
}
|
||||||
|
resourcePtr = resourceBuf;
|
||||||
|
while (resourcePtr[0] != '#') {
|
||||||
|
if (resourcePtr[0] == '@' && resourcePtr[1] == resid) {
|
||||||
|
resourcePtr += 5;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resourcePtr++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void res_Get(char *buf) {
|
||||||
|
int16 i = 0;
|
||||||
|
while (1) {
|
||||||
|
if (*resourcePtr == '\r')
|
||||||
|
resourcePtr++;
|
||||||
|
|
||||||
|
if (*resourcePtr == '\n') {
|
||||||
|
resourcePtr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[i] = *resourcePtr;
|
||||||
|
i++;
|
||||||
|
resourcePtr++;
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
20
gob/resource.h
Normal file
20
gob/resource.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __RESOURCE_H
|
||||||
|
#define __RESOURCE_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void res_Free(void);
|
||||||
|
void res_Init(void);
|
||||||
|
void res_Search(char resid);
|
||||||
|
void res_Get(char *buf);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
738
gob/scenery.cpp
Normal file
738
gob/scenery.cpp
Normal file
|
@ -0,0 +1,738 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/scenery.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/inter.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/draw.h"
|
||||||
|
#include "gob/game.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/anim.h"
|
||||||
|
#include "gob/parse.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 scen_spriteResId[20];
|
||||||
|
char scen_spriteRefs[20];
|
||||||
|
|
||||||
|
Scen_Static scen_statics[10];
|
||||||
|
int16 scen_staticPictCount[10];
|
||||||
|
char scen_staticFromExt[10];
|
||||||
|
int16 scen_staticResId[10];
|
||||||
|
char scen_staticPictToSprite[70];
|
||||||
|
|
||||||
|
Scen_Animation scen_animations[10];
|
||||||
|
int16 scen_animPictCount[10];
|
||||||
|
char scen_animFromExt[10];
|
||||||
|
int16 scen_animResId[10];
|
||||||
|
char scen_animPictToSprite[70];
|
||||||
|
|
||||||
|
int16 scen_curStatic;
|
||||||
|
int16 scen_curStaticLayer;
|
||||||
|
|
||||||
|
int16 scen_toRedrawLeft;
|
||||||
|
int16 scen_toRedrawRight;
|
||||||
|
int16 scen_toRedrawTop;
|
||||||
|
int16 scen_toRedrawBottom;
|
||||||
|
|
||||||
|
int16 scen_animTop;
|
||||||
|
int16 scen_animLeft;
|
||||||
|
|
||||||
|
int16 *scen_pCaptureCounter;
|
||||||
|
|
||||||
|
int16 scen_loadStatic(char search) {
|
||||||
|
int16 tmp;
|
||||||
|
int16 *backsPtr;
|
||||||
|
int16 picsCount;
|
||||||
|
int16 resId;
|
||||||
|
int16 i;
|
||||||
|
int16 sceneryIndex;
|
||||||
|
char *dataPtr;
|
||||||
|
Scen_Static *ptr;
|
||||||
|
int16 offset;
|
||||||
|
int16 pictDescId;
|
||||||
|
int16 width;
|
||||||
|
int16 height;
|
||||||
|
int16 sprResId;
|
||||||
|
int16 sprIndex;
|
||||||
|
|
||||||
|
inter_evalExpr(&sceneryIndex);
|
||||||
|
tmp = inter_load16();
|
||||||
|
backsPtr = (int16 *)inter_execPtr;
|
||||||
|
inter_execPtr += tmp * 2;
|
||||||
|
picsCount = inter_load16();
|
||||||
|
resId = inter_load16();
|
||||||
|
if (search) {
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
if (scen_staticPictCount[i] != -1 && scen_staticResId[i] == resId) {
|
||||||
|
inter_execPtr += 8 * scen_staticPictCount[i];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scen_staticPictCount[i] == -1 && i < sceneryIndex)
|
||||||
|
sceneryIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scen_staticPictCount[sceneryIndex] = picsCount;
|
||||||
|
scen_staticResId[sceneryIndex] = resId;
|
||||||
|
|
||||||
|
if (resId >= 30000) {
|
||||||
|
scen_staticFromExt[sceneryIndex] = 1;
|
||||||
|
dataPtr = game_loadExtData(resId, 0, 0);
|
||||||
|
} else {
|
||||||
|
scen_staticFromExt[sceneryIndex] = 0;
|
||||||
|
dataPtr = game_loadTotResource(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = &scen_statics[sceneryIndex];
|
||||||
|
ptr->dataPtr = dataPtr;
|
||||||
|
|
||||||
|
ptr->layersCount = (int16)READ_LE_UINT16(dataPtr);
|
||||||
|
dataPtr += 2;
|
||||||
|
debug("layer: %d", ptr->layersCount);
|
||||||
|
|
||||||
|
ptr->layers = (Scen_StaticLayer **)malloc(sizeof(Scen_StaticLayer *) * ptr->layersCount);
|
||||||
|
ptr->pieces = (Scen_PieceDesc **)malloc(sizeof(Scen_PieceDesc *) * picsCount);
|
||||||
|
|
||||||
|
for (i = 0; i < ptr->layersCount; i++) {
|
||||||
|
offset = ((int16 *)dataPtr)[i];
|
||||||
|
ptr->layers[i] = (Scen_StaticLayer *)(dataPtr + offset - 2);
|
||||||
|
ptr->layers[i]->backResId = *backsPtr;
|
||||||
|
backsPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < picsCount; i++) {
|
||||||
|
pictDescId = inter_load16();
|
||||||
|
if (resId >= 30000) {
|
||||||
|
ptr->pieces[i] =
|
||||||
|
(Scen_PieceDesc *) game_loadExtData(pictDescId, 0,
|
||||||
|
0);
|
||||||
|
} else {
|
||||||
|
ptr->pieces[i] =
|
||||||
|
(Scen_PieceDesc *)
|
||||||
|
game_loadTotResource(pictDescId);
|
||||||
|
}
|
||||||
|
|
||||||
|
width = inter_load16();
|
||||||
|
height = inter_load16();
|
||||||
|
sprResId = inter_load16();
|
||||||
|
for (sprIndex = 0; sprIndex < 20; sprIndex++) {
|
||||||
|
if (scen_spriteResId[sprIndex] == sprResId)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprIndex < 20) {
|
||||||
|
scen_staticPictToSprite[7 * sceneryIndex + i] =
|
||||||
|
sprIndex;
|
||||||
|
scen_spriteRefs[sprIndex]++;
|
||||||
|
} else {
|
||||||
|
for (sprIndex = 19; draw_spritesArray[sprIndex] != 0;
|
||||||
|
sprIndex--);
|
||||||
|
|
||||||
|
scen_staticPictToSprite[7 * sceneryIndex + i] =
|
||||||
|
sprIndex;
|
||||||
|
scen_spriteRefs[sprIndex] = 1;
|
||||||
|
scen_spriteResId[sprIndex] = sprResId;
|
||||||
|
draw_spritesArray[sprIndex] =
|
||||||
|
vid_initSurfDesc(videoMode, width, height, 2);
|
||||||
|
|
||||||
|
vid_clearSurf(draw_spritesArray[sprIndex]);
|
||||||
|
draw_destSurface = sprIndex;
|
||||||
|
draw_spriteLeft = sprResId;
|
||||||
|
draw_transparency = 0;
|
||||||
|
draw_destSpriteX = 0;
|
||||||
|
draw_destSpriteY = 0;
|
||||||
|
draw_spriteOperation(DRAW_LOADSPRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sceneryIndex + 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_freeStatic(int16 index) {
|
||||||
|
int16 i;
|
||||||
|
int16 spr;
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
inter_evalExpr(&index);
|
||||||
|
|
||||||
|
if (scen_staticPictCount[index] == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < scen_staticPictCount[index]; i++) {
|
||||||
|
if (scen_staticFromExt[index] == 1)
|
||||||
|
free((char *)scen_statics[index].pieces[i]);
|
||||||
|
|
||||||
|
spr = scen_staticPictToSprite[index * 7 + i];
|
||||||
|
scen_spriteRefs[spr]--;
|
||||||
|
if (scen_spriteRefs[spr] == 0) {
|
||||||
|
vid_freeSurfDesc(draw_spritesArray[spr]);
|
||||||
|
draw_spritesArray[spr] = 0;
|
||||||
|
scen_spriteResId[spr] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char *)scen_statics[index].layers);
|
||||||
|
free((char *)scen_statics[index].pieces);
|
||||||
|
if (scen_staticFromExt[index] == 1)
|
||||||
|
free((char *)scen_statics[index].dataPtr);
|
||||||
|
|
||||||
|
scen_staticFromExt[index] = 0;
|
||||||
|
scen_staticPictCount[index] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_renderStatic(int16 scenery, int16 layer) {
|
||||||
|
Scen_Static *ptr;
|
||||||
|
Scen_StaticLayer *layerPtr;
|
||||||
|
Scen_StaticPlane *planePtr;
|
||||||
|
int16 planeCount;
|
||||||
|
int16 order;
|
||||||
|
int16 plane;
|
||||||
|
|
||||||
|
int16 pieceIndex;
|
||||||
|
int16 pictIndex;
|
||||||
|
|
||||||
|
int16 left;
|
||||||
|
int16 right;
|
||||||
|
int16 top;
|
||||||
|
int16 bottom;
|
||||||
|
|
||||||
|
ptr = &scen_statics[scenery];
|
||||||
|
if (layer >= ptr->layersCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layerPtr = ptr->layers[layer];
|
||||||
|
|
||||||
|
draw_spriteLeft = layerPtr->backResId;
|
||||||
|
if (draw_spriteLeft != -1) {
|
||||||
|
draw_destSpriteX = 0;
|
||||||
|
draw_destSpriteY = 0;
|
||||||
|
draw_destSurface = 21;
|
||||||
|
draw_transparency = 0;
|
||||||
|
draw_spriteOperation(DRAW_LOADSPRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
planeCount = layerPtr->planeCount;
|
||||||
|
for (order = 0; order < 10; order++) {
|
||||||
|
for (plane = 0, planePtr = layerPtr->planes;
|
||||||
|
plane < planeCount; plane++, planePtr++) {
|
||||||
|
if (planePtr->drawOrder != order)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pieceIndex = planePtr->pieceIndex;
|
||||||
|
pictIndex = planePtr->pictIndex - 1;
|
||||||
|
|
||||||
|
draw_destSpriteX = planePtr->destX;
|
||||||
|
draw_destSpriteY = planePtr->destY;
|
||||||
|
left = ptr->pieces[pictIndex][pieceIndex].left;
|
||||||
|
right = ptr->pieces[pictIndex][pieceIndex].right;
|
||||||
|
top = ptr->pieces[pictIndex][pieceIndex].top;
|
||||||
|
bottom = ptr->pieces[pictIndex][pieceIndex].bottom;
|
||||||
|
|
||||||
|
draw_sourceSurface =
|
||||||
|
scen_staticPictToSprite[scenery * 7 + pictIndex];
|
||||||
|
draw_destSurface = 21;
|
||||||
|
draw_spriteLeft = left;
|
||||||
|
draw_spriteTop = top;
|
||||||
|
draw_spriteRight = right - left + 1;
|
||||||
|
draw_spriteBottom = bottom - top + 1;
|
||||||
|
draw_transparency = planePtr->transp ? 3 : 0;
|
||||||
|
draw_spriteOperation(DRAW_BLITSURF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_interRenderStatic(void) {
|
||||||
|
int16 layer;
|
||||||
|
int16 index;
|
||||||
|
|
||||||
|
inter_evalExpr(&index);
|
||||||
|
inter_evalExpr(&layer);
|
||||||
|
scen_renderStatic(index, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_interLoadCurLayer(void) {
|
||||||
|
inter_evalExpr(&scen_curStatic);
|
||||||
|
inter_evalExpr(&scen_curStaticLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_updateStatic(int16 orderFrom) {
|
||||||
|
Scen_StaticLayer *layerPtr;
|
||||||
|
Scen_PieceDesc **pictPtr;
|
||||||
|
Scen_StaticPlane *planePtr;
|
||||||
|
int16 planeCount;
|
||||||
|
int16 order;
|
||||||
|
int16 plane;
|
||||||
|
int16 pieceIndex;
|
||||||
|
int16 pictIndex;
|
||||||
|
|
||||||
|
int16 left;
|
||||||
|
int16 right;
|
||||||
|
int16 top;
|
||||||
|
int16 bottom;
|
||||||
|
|
||||||
|
if (scen_curStatic == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (scen_curStaticLayer >= scen_statics[scen_curStatic].layersCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layerPtr = scen_statics[scen_curStatic].layers[scen_curStaticLayer];
|
||||||
|
pictPtr = scen_statics[scen_curStatic].pieces;
|
||||||
|
|
||||||
|
planeCount = layerPtr->planeCount;
|
||||||
|
|
||||||
|
for (order = orderFrom; order < 10; order++) {
|
||||||
|
for (planePtr = layerPtr->planes, plane = 0;
|
||||||
|
plane < planeCount; plane++, planePtr++) {
|
||||||
|
if (planePtr->drawOrder != order)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pieceIndex = planePtr->pieceIndex;
|
||||||
|
pictIndex = planePtr->pictIndex - 1;
|
||||||
|
draw_destSpriteX = planePtr->destX;
|
||||||
|
draw_destSpriteY = planePtr->destY;
|
||||||
|
|
||||||
|
left = pictPtr[pictIndex][pieceIndex].left;
|
||||||
|
right = pictPtr[pictIndex][pieceIndex].right;
|
||||||
|
top = pictPtr[pictIndex][pieceIndex].top;
|
||||||
|
bottom = pictPtr[pictIndex][pieceIndex].bottom;
|
||||||
|
|
||||||
|
if (draw_destSpriteX > scen_toRedrawRight)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (draw_destSpriteY > scen_toRedrawBottom)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (draw_destSpriteX < scen_toRedrawLeft) {
|
||||||
|
left += scen_toRedrawLeft - draw_destSpriteX;
|
||||||
|
draw_destSpriteX = scen_toRedrawLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_destSpriteY < scen_toRedrawTop) {
|
||||||
|
top += scen_toRedrawTop - draw_destSpriteY;
|
||||||
|
draw_destSpriteY = scen_toRedrawTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_spriteLeft = left;
|
||||||
|
draw_spriteTop = top;
|
||||||
|
draw_spriteRight = right - left + 1;
|
||||||
|
draw_spriteBottom = bottom - top + 1;
|
||||||
|
|
||||||
|
if (draw_spriteRight <= 0 || draw_spriteBottom <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (draw_destSpriteX + draw_spriteRight - 1 >
|
||||||
|
scen_toRedrawRight)
|
||||||
|
draw_spriteRight =
|
||||||
|
scen_toRedrawRight - draw_destSpriteX + 1;
|
||||||
|
|
||||||
|
if (draw_destSpriteY + draw_spriteBottom - 1 >
|
||||||
|
scen_toRedrawBottom)
|
||||||
|
draw_spriteBottom =
|
||||||
|
scen_toRedrawBottom - draw_destSpriteY + 1;
|
||||||
|
|
||||||
|
draw_sourceSurface =
|
||||||
|
scen_staticPictToSprite[scen_curStatic * 7 +
|
||||||
|
pictIndex];
|
||||||
|
draw_destSurface = 21;
|
||||||
|
draw_transparency = planePtr->transp ? 3 : 0;
|
||||||
|
draw_spriteOperation(DRAW_BLITSURF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 scen_loadAnim(char search) {
|
||||||
|
int16 picsCount;
|
||||||
|
int16 resId;
|
||||||
|
int16 i;
|
||||||
|
int16 sceneryIndex;
|
||||||
|
char *dataPtr;
|
||||||
|
Scen_Animation *ptr;
|
||||||
|
int16 offset;
|
||||||
|
int16 pictDescId;
|
||||||
|
int16 width;
|
||||||
|
int16 height;
|
||||||
|
int16 sprResId;
|
||||||
|
int16 sprIndex;
|
||||||
|
|
||||||
|
inter_evalExpr(&sceneryIndex);
|
||||||
|
picsCount = inter_load16();
|
||||||
|
resId = inter_load16();
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
if (scen_animPictCount[i] != 0
|
||||||
|
&& scen_animResId[i] == resId) {
|
||||||
|
inter_execPtr += 8 * scen_animPictCount[i];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scen_animPictCount[i] == 0 && i < sceneryIndex)
|
||||||
|
sceneryIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scen_animPictCount[sceneryIndex] = picsCount;
|
||||||
|
scen_animResId[sceneryIndex] = resId;
|
||||||
|
|
||||||
|
if (resId >= 30000) {
|
||||||
|
scen_animFromExt[sceneryIndex] = 1;
|
||||||
|
dataPtr = game_loadExtData(resId, 0, 0);
|
||||||
|
} else {
|
||||||
|
scen_animFromExt[sceneryIndex] = 0;
|
||||||
|
dataPtr = game_loadTotResource(resId);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = &scen_animations[sceneryIndex];
|
||||||
|
ptr->dataPtr = dataPtr;
|
||||||
|
|
||||||
|
ptr->layersCount = READ_LE_UINT16(dataPtr);
|
||||||
|
dataPtr += 2;
|
||||||
|
|
||||||
|
ptr->layers =
|
||||||
|
(Scen_AnimLayer **) malloc(sizeof(Scen_AnimLayer *) *
|
||||||
|
ptr->layersCount);
|
||||||
|
ptr->pieces =
|
||||||
|
(Scen_PieceDesc **) malloc(sizeof(Scen_PieceDesc *) *
|
||||||
|
picsCount);
|
||||||
|
|
||||||
|
for (i = 0; i < ptr->layersCount; i++) {
|
||||||
|
offset = ((int16 *)dataPtr)[i];
|
||||||
|
ptr->layers[i] = (Scen_AnimLayer *) (dataPtr + offset - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < picsCount; i++) {
|
||||||
|
pictDescId = inter_load16();
|
||||||
|
if (resId >= 30000) {
|
||||||
|
ptr->pieces[i] =
|
||||||
|
(Scen_PieceDesc *) game_loadExtData(pictDescId, 0,
|
||||||
|
0);
|
||||||
|
} else {
|
||||||
|
ptr->pieces[i] =
|
||||||
|
(Scen_PieceDesc *)
|
||||||
|
game_loadTotResource(pictDescId);
|
||||||
|
}
|
||||||
|
|
||||||
|
width = inter_load16();
|
||||||
|
height = inter_load16();
|
||||||
|
sprResId = inter_load16();
|
||||||
|
for (sprIndex = 0; sprIndex < 20; sprIndex++) {
|
||||||
|
if (scen_spriteResId[sprIndex] == sprResId)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprIndex < 20) {
|
||||||
|
scen_animPictToSprite[7 * sceneryIndex + i] = sprIndex;
|
||||||
|
scen_spriteRefs[sprIndex]++;
|
||||||
|
} else {
|
||||||
|
for (sprIndex = 19; draw_spritesArray[sprIndex] != 0;
|
||||||
|
sprIndex--);
|
||||||
|
|
||||||
|
scen_animPictToSprite[7 * sceneryIndex + i] = sprIndex;
|
||||||
|
scen_spriteRefs[sprIndex] = 1;
|
||||||
|
scen_spriteResId[sprIndex] = sprResId;
|
||||||
|
draw_spritesArray[sprIndex] =
|
||||||
|
vid_initSurfDesc(videoMode, width, height, 2);
|
||||||
|
|
||||||
|
vid_clearSurf(draw_spritesArray[sprIndex]);
|
||||||
|
draw_destSurface = sprIndex;
|
||||||
|
draw_spriteLeft = sprResId;
|
||||||
|
draw_transparency = 0;
|
||||||
|
draw_destSpriteX = 0;
|
||||||
|
draw_destSpriteY = 0;
|
||||||
|
draw_spriteOperation(DRAW_LOADSPRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sceneryIndex + 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// flags & 1 - do capture all area animation is occupying
|
||||||
|
// flags & 4 == 0 - calculate animation final size
|
||||||
|
// flags & 2 != 0 - don't check with "toRedraw"'s
|
||||||
|
// flags & 4 != 0 - checkk view toRedraw
|
||||||
|
void scen_updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
|
||||||
|
int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
|
||||||
|
Scen_AnimLayer *layerPtr;
|
||||||
|
Scen_PieceDesc **pictPtr;
|
||||||
|
Scen_AnimFramePiece *framePtr;
|
||||||
|
|
||||||
|
uint16 pieceIndex;
|
||||||
|
uint16 pictIndex;
|
||||||
|
|
||||||
|
int16 left;
|
||||||
|
int16 right;
|
||||||
|
int16 top;
|
||||||
|
int16 bottom;
|
||||||
|
|
||||||
|
byte highX;
|
||||||
|
byte highY;
|
||||||
|
|
||||||
|
int16 i;
|
||||||
|
int16 transp;
|
||||||
|
|
||||||
|
int16 destX;
|
||||||
|
int16 destY;
|
||||||
|
|
||||||
|
if (layer >= scen_animations[animation].layersCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layerPtr = scen_animations[animation].layers[layer];
|
||||||
|
|
||||||
|
if (frame >= layerPtr->framesCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (flags & 1) // Do capture
|
||||||
|
{
|
||||||
|
scen_updateAnim(layer, frame, animation, 0, drawDeltaX,
|
||||||
|
drawDeltaY, 0);
|
||||||
|
|
||||||
|
if (scen_toRedrawLeft == -12345) // Some magic number?
|
||||||
|
return;
|
||||||
|
|
||||||
|
game_capturePush(scen_toRedrawLeft, scen_toRedrawTop,
|
||||||
|
scen_toRedrawRight - scen_toRedrawLeft + 1,
|
||||||
|
scen_toRedrawBottom - scen_toRedrawTop + 1);
|
||||||
|
|
||||||
|
*scen_pCaptureCounter = *scen_pCaptureCounter + 1;
|
||||||
|
}
|
||||||
|
pictPtr = scen_animations[animation].pieces;
|
||||||
|
framePtr = layerPtr->frames;
|
||||||
|
|
||||||
|
for (i = 0; i < frame; i++, framePtr++) {
|
||||||
|
while (framePtr->notFinal == 1)
|
||||||
|
framePtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & 4) == 0) {
|
||||||
|
scen_toRedrawLeft = -12345;
|
||||||
|
} else {
|
||||||
|
scen_toRedrawLeft =
|
||||||
|
MAX(scen_toRedrawLeft, anim_animAreaLeft);
|
||||||
|
scen_toRedrawTop =
|
||||||
|
MAX(scen_toRedrawTop, anim_animAreaTop);
|
||||||
|
scen_toRedrawRight =
|
||||||
|
MIN(scen_toRedrawRight,
|
||||||
|
anim_animAreaLeft + anim_animAreaWidth - 1);
|
||||||
|
scen_toRedrawBottom =
|
||||||
|
MIN(scen_toRedrawBottom,
|
||||||
|
anim_animAreaTop + anim_animAreaHeight - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
transp = layerPtr->transp ? 3 : 0;
|
||||||
|
|
||||||
|
framePtr--;
|
||||||
|
do {
|
||||||
|
framePtr++;
|
||||||
|
|
||||||
|
pieceIndex = framePtr->pieceIndex;
|
||||||
|
pictIndex = framePtr->pictIndex;
|
||||||
|
|
||||||
|
destX = framePtr->destX;
|
||||||
|
destY = framePtr->destY;
|
||||||
|
|
||||||
|
highX = pictIndex & 0xc0;
|
||||||
|
highY = pictIndex & 0x30;
|
||||||
|
highX >>= 6;
|
||||||
|
highY >>= 4;
|
||||||
|
if (destX >= 0)
|
||||||
|
destX += ((uint16)highX) << 7;
|
||||||
|
else
|
||||||
|
destX -= ((uint16)highX) << 7;
|
||||||
|
|
||||||
|
if (destY >= 0)
|
||||||
|
destY += ((uint16)highY) << 7;
|
||||||
|
else
|
||||||
|
destY -= ((uint16)highY) << 7;
|
||||||
|
|
||||||
|
if (drawDeltaX == 1000)
|
||||||
|
destX += layerPtr->posX;
|
||||||
|
else
|
||||||
|
destX += drawDeltaX;
|
||||||
|
|
||||||
|
if (drawDeltaY == 1000)
|
||||||
|
destY += layerPtr->posY;
|
||||||
|
else
|
||||||
|
destY += drawDeltaY;
|
||||||
|
|
||||||
|
pictIndex = (pictIndex & 15) - 1;
|
||||||
|
|
||||||
|
left = pictPtr[pictIndex][pieceIndex].left;
|
||||||
|
right = pictPtr[pictIndex][pieceIndex].right;
|
||||||
|
top = pictPtr[pictIndex][pieceIndex].top;
|
||||||
|
bottom = pictPtr[pictIndex][pieceIndex].bottom;
|
||||||
|
|
||||||
|
if (flags & 2) {
|
||||||
|
if (destX < anim_animAreaLeft) {
|
||||||
|
left += anim_animAreaLeft - destX;
|
||||||
|
destX = anim_animAreaLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left <= right
|
||||||
|
&& destX + right - left >=
|
||||||
|
anim_animAreaLeft + anim_animAreaWidth)
|
||||||
|
right -=
|
||||||
|
(destX + right - left) -
|
||||||
|
(anim_animAreaLeft + anim_animAreaWidth) +
|
||||||
|
1;
|
||||||
|
|
||||||
|
if (destY < anim_animAreaTop) {
|
||||||
|
top += anim_animAreaTop - destY;
|
||||||
|
destY = anim_animAreaTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top <= bottom
|
||||||
|
&& destY + bottom - top >=
|
||||||
|
anim_animAreaTop + anim_animAreaHeight)
|
||||||
|
bottom -=
|
||||||
|
(destY + bottom - top) -
|
||||||
|
(anim_animAreaTop + anim_animAreaHeight) +
|
||||||
|
1;
|
||||||
|
|
||||||
|
} else if (flags & 4) {
|
||||||
|
if (destX < scen_toRedrawLeft) {
|
||||||
|
left += scen_toRedrawLeft - destX;
|
||||||
|
destX = scen_toRedrawLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left <= right
|
||||||
|
&& destX + right - left > scen_toRedrawRight)
|
||||||
|
right -=
|
||||||
|
destX + right - left - scen_toRedrawRight;
|
||||||
|
|
||||||
|
if (destY < scen_toRedrawTop) {
|
||||||
|
top += scen_toRedrawTop - destY;
|
||||||
|
destY = scen_toRedrawTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top <= bottom
|
||||||
|
&& destY + bottom - top > scen_toRedrawBottom)
|
||||||
|
bottom -=
|
||||||
|
destY + bottom - top - scen_toRedrawBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left > right || top > bottom)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (doDraw) {
|
||||||
|
draw_sourceSurface =
|
||||||
|
scen_animPictToSprite[animation * 7 + pictIndex];
|
||||||
|
draw_destSurface = 21;
|
||||||
|
|
||||||
|
draw_spriteLeft = left;
|
||||||
|
draw_spriteTop = top;
|
||||||
|
draw_spriteRight = right - left + 1;
|
||||||
|
draw_spriteBottom = bottom - top + 1;
|
||||||
|
draw_destSpriteX = destX;
|
||||||
|
draw_destSpriteY = destY;
|
||||||
|
draw_transparency = transp;
|
||||||
|
draw_spriteOperation(DRAW_BLITSURF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & 4) == 0) {
|
||||||
|
if (scen_toRedrawLeft == -12345) {
|
||||||
|
scen_toRedrawLeft = destX;
|
||||||
|
scen_animLeft = destX;
|
||||||
|
scen_toRedrawTop = destY;
|
||||||
|
scen_animTop = destY;
|
||||||
|
scen_toRedrawRight = destX + right - left;
|
||||||
|
scen_toRedrawBottom = destY + bottom - top;
|
||||||
|
} else {
|
||||||
|
scen_toRedrawLeft =
|
||||||
|
MIN(scen_toRedrawLeft, destX);
|
||||||
|
scen_toRedrawTop =
|
||||||
|
MIN(scen_toRedrawTop, destY);
|
||||||
|
scen_toRedrawRight =
|
||||||
|
MAX(scen_toRedrawRight,
|
||||||
|
destX + right - left);
|
||||||
|
scen_toRedrawBottom =
|
||||||
|
MAX(scen_toRedrawBottom,
|
||||||
|
destY + bottom - top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (framePtr->notFinal == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_freeAnim(int16 animation) {
|
||||||
|
int16 i;
|
||||||
|
int16 spr;
|
||||||
|
|
||||||
|
if (animation == -1)
|
||||||
|
inter_evalExpr(&animation);
|
||||||
|
|
||||||
|
if (scen_animPictCount[animation] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < scen_animPictCount[animation]; i++) {
|
||||||
|
if (scen_animFromExt[animation] == 1)
|
||||||
|
free((char *)scen_animations[animation].pieces[i]);
|
||||||
|
|
||||||
|
spr = scen_animPictToSprite[animation * 7 + i];
|
||||||
|
scen_spriteRefs[spr]--;
|
||||||
|
if (scen_spriteRefs[spr] == 0) {
|
||||||
|
vid_freeSurfDesc(draw_spritesArray[spr]);
|
||||||
|
|
||||||
|
draw_spritesArray[spr] = 0;
|
||||||
|
scen_spriteResId[spr] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char *)scen_animations[animation].layers);
|
||||||
|
free((char *)scen_animations[animation].pieces);
|
||||||
|
if (scen_animFromExt[animation] == 1)
|
||||||
|
free(scen_animations[animation].dataPtr);
|
||||||
|
|
||||||
|
scen_animFromExt[animation] = 0;
|
||||||
|
scen_animPictCount[animation] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_interUpdateAnim(void) {
|
||||||
|
int16 deltaX;
|
||||||
|
int16 deltaY;
|
||||||
|
int16 flags;
|
||||||
|
int16 frame;
|
||||||
|
int16 layer;
|
||||||
|
int16 animation;
|
||||||
|
|
||||||
|
inter_evalExpr(&deltaX);
|
||||||
|
inter_evalExpr(&deltaY);
|
||||||
|
inter_evalExpr(&animation);
|
||||||
|
inter_evalExpr(&layer);
|
||||||
|
inter_evalExpr(&frame);
|
||||||
|
flags = inter_load16();
|
||||||
|
scen_updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scen_interStoreParams(void) {
|
||||||
|
Scen_AnimLayer *layerPtr;
|
||||||
|
int16 animation;
|
||||||
|
int16 layer;
|
||||||
|
int16 var;
|
||||||
|
|
||||||
|
log_write("scen_interStoreParams: Storing...\n");
|
||||||
|
|
||||||
|
inter_evalExpr(&animation);
|
||||||
|
inter_evalExpr(&layer);
|
||||||
|
layerPtr = scen_animations[animation].layers[layer];
|
||||||
|
|
||||||
|
var = parse_parseVarIndex();
|
||||||
|
WRITE_LE_UINT32(inter_variables + var, layerPtr->animDeltaX);
|
||||||
|
|
||||||
|
var = parse_parseVarIndex();
|
||||||
|
WRITE_LE_UINT32(inter_variables + var, layerPtr->animDeltaY);
|
||||||
|
|
||||||
|
var = parse_parseVarIndex();
|
||||||
|
WRITE_LE_UINT32(inter_variables + var, layerPtr->unknown0);
|
||||||
|
|
||||||
|
var = parse_parseVarIndex();
|
||||||
|
WRITE_LE_UINT32(inter_variables + var, layerPtr->framesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
121
gob/scenery.h
Normal file
121
gob/scenery.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __SCENERY_H
|
||||||
|
#define __SCENERY_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#pragma START_PACK_STRUCTS
|
||||||
|
typedef struct Scen_PieceDesc {
|
||||||
|
int16 left;
|
||||||
|
int16 right;
|
||||||
|
int16 top;
|
||||||
|
int16 bottom;
|
||||||
|
} GCC_PACK Scen_PieceDesc;
|
||||||
|
|
||||||
|
typedef struct Scen_StaticPlane {
|
||||||
|
char pictIndex;
|
||||||
|
char pieceIndex;
|
||||||
|
char drawOrder;
|
||||||
|
int16 destX;
|
||||||
|
int16 destY;
|
||||||
|
char transp;
|
||||||
|
} GCC_PACK Scen_StaticPlane;
|
||||||
|
|
||||||
|
typedef struct Scen_StaticLayer {
|
||||||
|
int16 backResId;
|
||||||
|
int16 planeCount;
|
||||||
|
Scen_StaticPlane planes[1];
|
||||||
|
} GCC_PACK Scen_StaticLayer;
|
||||||
|
|
||||||
|
typedef struct Scen_Static {
|
||||||
|
int16 layersCount;
|
||||||
|
Scen_StaticLayer **layers;
|
||||||
|
Scen_PieceDesc **pieces;
|
||||||
|
void *unknown;
|
||||||
|
char *dataPtr;
|
||||||
|
} GCC_PACK Scen_Static;
|
||||||
|
|
||||||
|
// Animations
|
||||||
|
|
||||||
|
typedef struct Scen_AnimFramePiece {
|
||||||
|
byte pictIndex;
|
||||||
|
byte pieceIndex;
|
||||||
|
char destX;
|
||||||
|
char destY;
|
||||||
|
char notFinal;
|
||||||
|
} GCC_PACK Scen_AnimFramePiece;
|
||||||
|
|
||||||
|
typedef struct Scen_AnimLayer {
|
||||||
|
int16 unknown0;
|
||||||
|
int16 posX;
|
||||||
|
int16 posY;
|
||||||
|
int16 animDeltaX;
|
||||||
|
int16 animDeltaY;
|
||||||
|
char transp;
|
||||||
|
int16 framesCount;
|
||||||
|
Scen_AnimFramePiece frames[1];
|
||||||
|
} GCC_PACK Scen_AnimLayer;
|
||||||
|
#pragma END_PACK_STRUCTS
|
||||||
|
|
||||||
|
struct Scen_Animation {
|
||||||
|
int16 layersCount;
|
||||||
|
Scen_AnimLayer **layers;
|
||||||
|
Scen_PieceDesc **pieces;
|
||||||
|
void *unknowm;
|
||||||
|
char *dataPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global variables
|
||||||
|
|
||||||
|
extern char scen_spriteRefs[20];
|
||||||
|
extern int16 scen_spriteResId[20];
|
||||||
|
|
||||||
|
extern char scen_staticPictToSprite[70];
|
||||||
|
extern int16 scen_staticPictCount[10];
|
||||||
|
extern Scen_Static scen_statics[10];
|
||||||
|
extern char scen_staticFromExt[10];
|
||||||
|
extern int16 scen_staticResId[10];
|
||||||
|
|
||||||
|
extern char scen_animPictToSprite[70];
|
||||||
|
extern int16 scen_animPictCount[10];
|
||||||
|
extern char scen_animFromExt[10];
|
||||||
|
extern Scen_Animation scen_animations[10];
|
||||||
|
extern int16 scen_animResId[10];
|
||||||
|
|
||||||
|
extern int16 scen_curStatic;
|
||||||
|
extern int16 scen_curStaticLayer;
|
||||||
|
|
||||||
|
extern int16 scen_toRedrawLeft;
|
||||||
|
extern int16 scen_toRedrawRight;
|
||||||
|
extern int16 scen_toRedrawTop;
|
||||||
|
extern int16 scen_toRedrawBottom;
|
||||||
|
|
||||||
|
extern int16 scen_animTop;
|
||||||
|
extern int16 scen_animLeft;
|
||||||
|
|
||||||
|
extern int16 *scen_pCaptureCounter;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
int16 scen_loadStatic(char search);
|
||||||
|
void scen_freeStatic(int16 index);
|
||||||
|
void scen_renderStatic(int16 scenery, int16 layer);
|
||||||
|
void scen_interRenderStatic(void);
|
||||||
|
void scen_interLoadCurLayer(void);
|
||||||
|
void scen_updateStatic(int16 orderFrom);
|
||||||
|
int16 scen_loadAnim(char search);
|
||||||
|
void scen_updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
|
||||||
|
int16 drawDeltaX, int16 drawDeltaY, char doDraw);
|
||||||
|
void scen_freeAnim(int16 animation);
|
||||||
|
void scen_interUpdateAnim(void);
|
||||||
|
void scen_interStoreParams(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif /* __SCENERY_H */
|
44
gob/sound.cpp
Normal file
44
gob/sound.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
namespace Gob {
|
||||||
|
int16 snd_checkProAudio(void) {return 0;}
|
||||||
|
int16 snd_checkAdlib(void) {return 0;}
|
||||||
|
int16 snd_checkBlaster(void) {return 0;}
|
||||||
|
void snd_setBlasterPort(int16 port) {return;}
|
||||||
|
void snd_speakerOn(int16 frequency) {return;}
|
||||||
|
void snd_speakerOff(void) {return;}
|
||||||
|
void snd_stopSound(int16 arg){return;}
|
||||||
|
void snd_setResetTimerFlag(char flag){return;}
|
||||||
|
|
||||||
|
void snd_playSample(Snd_SoundDesc * soundDesc, int16 repCount, int16 frequency) {;}
|
||||||
|
void snd_cleanupFuncCallback() {;}
|
||||||
|
CleanupFuncPtr (snd_cleanupFunc);
|
||||||
|
//CleanupFuncPtr snd_cleanupFunc;// = &snd_cleanupFuncCallback();
|
||||||
|
|
||||||
|
int16 snd_soundPort;
|
||||||
|
char snd_playingSound;
|
||||||
|
|
||||||
|
void snd_writeAdlib(int16 port, int16 data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Snd_SoundDesc *snd_loadSoundData(char *path) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void snd_freeSoundData(Snd_SoundDesc * sndDesc) {;}
|
||||||
|
void snd_playComposition(Snd_SoundDesc ** samples, int16 *composit, int16 freqVal) {;}
|
||||||
|
void snd_waitEndPlay(void) {;}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
|
||||||
|
|
47
gob/sound.h
Normal file
47
gob/sound.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __SOUND_H
|
||||||
|
#define __SOUND_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
int16 snd_checkProAudio(void);
|
||||||
|
int16 snd_checkAdlib(void);
|
||||||
|
int16 snd_checkBlaster(void);
|
||||||
|
void snd_setBlasterPort(int16 port);
|
||||||
|
void snd_speakerOn(int16 frequency);
|
||||||
|
void snd_speakerOff(void);
|
||||||
|
void snd_stopSound(int16 arg);
|
||||||
|
void snd_setResetTimerFlag(char flag);
|
||||||
|
|
||||||
|
extern int16 snd_soundPort;
|
||||||
|
extern char snd_playingSound;
|
||||||
|
|
||||||
|
typedef void (*CleanupFuncPtr) (int16);
|
||||||
|
extern CleanupFuncPtr snd_cleanupFunc;
|
||||||
|
|
||||||
|
void snd_writeAdlib(int16 port, int16 data);
|
||||||
|
|
||||||
|
typedef struct Snd_SoundDesc {
|
||||||
|
char *data;
|
||||||
|
int32 size;
|
||||||
|
int16 timerTicks;
|
||||||
|
int16 inClocks;
|
||||||
|
int16 frequency;
|
||||||
|
int16 flag;
|
||||||
|
} Snd_SoundDesc;
|
||||||
|
|
||||||
|
void snd_playSample(Snd_SoundDesc * soundDesc, int16 repCount, int16 frequency);
|
||||||
|
Snd_SoundDesc *snd_loadSoundData(char *path);
|
||||||
|
void snd_freeSoundData(Snd_SoundDesc * sndDesc);
|
||||||
|
void snd_playComposition(Snd_SoundDesc ** samples, int16 *composit, int16 freqVal);
|
||||||
|
void snd_waitEndPlay(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
21
gob/timer.cpp
Normal file
21
gob/timer.cpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/sound.h"
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
void timer_enableTimer() {
|
||||||
|
debug(0, "STUB: timer_enableTimer()");
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_disableTimer() {
|
||||||
|
debug(0, "STUB: timer_disableTimer()");
|
||||||
|
}
|
||||||
|
};
|
25
gob/timer.h
Normal file
25
gob/timer.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __TIMER_H_
|
||||||
|
#define __TIMER_H_
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
typedef void (* TickHandler) (void);
|
||||||
|
|
||||||
|
void timer_enableTimer(void);
|
||||||
|
void timer_disableTimer(void);
|
||||||
|
void timer_setHandler(void);
|
||||||
|
void timer_restoreHandler(void);
|
||||||
|
void timer_addTicks(int16 ticks);
|
||||||
|
void timer_setTickHandler(TickHandler handler);
|
||||||
|
int32 timer_getTicks(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
465
gob/util.cpp
Normal file
465
gob/util.cpp
Normal file
|
@ -0,0 +1,465 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/timer.h"
|
||||||
|
#include "gob/util.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/draw.h"
|
||||||
|
#include "gob/game.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
static int16 _mouseX, _mouseY, _keyPressed, _mouseButtons;
|
||||||
|
|
||||||
|
void util_initInput(void) {
|
||||||
|
_mouseX = _mouseY = _keyPressed = _mouseButtons = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_waitKey(void) {
|
||||||
|
while (_keyPressed) {
|
||||||
|
util_processInput();
|
||||||
|
g_system->delayMillis(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 util_translateKey(int16 key) {
|
||||||
|
struct keyS {
|
||||||
|
int16 from;
|
||||||
|
int16 to;
|
||||||
|
} static keys[] = {
|
||||||
|
8, 0xe08, // Backspace
|
||||||
|
13, 0x1C0D, // Enter
|
||||||
|
27, 0x11b, // ESC
|
||||||
|
127, 0x5300, // Del
|
||||||
|
273, 0x4800, // Up arrow
|
||||||
|
274, 0x5000, // Down arrow
|
||||||
|
275, 0x4D00, // Right arrow
|
||||||
|
276, 0x4B00, // Left arrow
|
||||||
|
282, 0x3b00, // F1
|
||||||
|
283, 0x3c00, // F2
|
||||||
|
284, 0x3d00, // F3
|
||||||
|
285, 0x3E00, // F4
|
||||||
|
286, 0x3F00, // F5
|
||||||
|
287, 0x4000, // F6
|
||||||
|
288, 0x4100, // F7
|
||||||
|
289, 0x4200, // F8
|
||||||
|
290, 0x4300, // F9
|
||||||
|
291, 0x4400 // F10
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(keys); i++)
|
||||||
|
if (key == keys[i].from)
|
||||||
|
return keys[i].to;
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 util_getKey(void) {
|
||||||
|
while (!_keyPressed) {
|
||||||
|
util_processInput();
|
||||||
|
|
||||||
|
if (_keyPressed)
|
||||||
|
break;
|
||||||
|
|
||||||
|
g_system->delayMillis(10);
|
||||||
|
}
|
||||||
|
return util_translateKey(_keyPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 util_checkKey(void) {
|
||||||
|
int key = _keyPressed;
|
||||||
|
|
||||||
|
if (_keyPressed)
|
||||||
|
_keyPressed = 0;
|
||||||
|
|
||||||
|
return util_translateKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 util_getRandom(int16 max) {
|
||||||
|
return ((int32)rand() * max) / (RAND_MAX + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_processInput() {
|
||||||
|
OSystem::Event event;
|
||||||
|
while (g_system->pollEvent(event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case OSystem::EVENT_MOUSEMOVE:
|
||||||
|
_mouseX = event.mouse.x;
|
||||||
|
_mouseY = event.mouse.y;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_LBUTTONDOWN:
|
||||||
|
_mouseButtons |= 1;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_RBUTTONDOWN:
|
||||||
|
_mouseButtons |= 2;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_LBUTTONUP:
|
||||||
|
_mouseButtons &= ~1;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_RBUTTONUP:
|
||||||
|
_mouseButtons &= ~2;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_KEYDOWN:
|
||||||
|
_keyPressed = event.kbd.keycode;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_KEYUP:
|
||||||
|
_keyPressed = 0;
|
||||||
|
break;
|
||||||
|
case OSystem::EVENT_QUIT:
|
||||||
|
g_system->quit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_getMouseState(int16 *pX, int16 *pY, int16 *pButtons) {
|
||||||
|
int16 x = 0;
|
||||||
|
int16 y = 0;
|
||||||
|
int16 buttons = 0;
|
||||||
|
|
||||||
|
*pX = _mouseX;
|
||||||
|
*pY = _mouseY;
|
||||||
|
|
||||||
|
if (pButtons != 0)
|
||||||
|
*pButtons = _mouseButtons;
|
||||||
|
// if (pX != 0)
|
||||||
|
// *pX = x >> mouseXShift;
|
||||||
|
// if (pY != 0)
|
||||||
|
// *pY = y >> mouseYShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_setMousePos(int16 x, int16 y) {
|
||||||
|
g_system->warpMouse(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_delay(uint16 msecs) {
|
||||||
|
g_system->delayMillis(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_beep(int16 freq) {
|
||||||
|
if (soundFlags == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//sound(freq);
|
||||||
|
util_delay(50);
|
||||||
|
//nosound();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 util_getTimeKey(void) {
|
||||||
|
return g_system->getMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_waitMouseUp(void) {
|
||||||
|
int16 x;
|
||||||
|
int16 y;
|
||||||
|
int16 buttons;
|
||||||
|
|
||||||
|
do {
|
||||||
|
util_getMouseState(&x, &y, &buttons);
|
||||||
|
} while (buttons != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_waitMouseDown(void) {
|
||||||
|
int16 x;
|
||||||
|
int16 y;
|
||||||
|
int16 buttons;
|
||||||
|
|
||||||
|
do {
|
||||||
|
util_getMouseState(&x, &y, &buttons);
|
||||||
|
} while (buttons == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOT IMPLEMENTED */
|
||||||
|
int16 util_calcDelayTime() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOT IMPLEMENTED */
|
||||||
|
void util_checkJoystick() {
|
||||||
|
useJoystick = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_setFrameRate(int16 rate) {
|
||||||
|
if (rate == 0)
|
||||||
|
rate = 1;
|
||||||
|
|
||||||
|
frameWaitTime = 1000 / rate;
|
||||||
|
startFrameTime = util_getTimeKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_waitEndFrame() {
|
||||||
|
int32 time;
|
||||||
|
|
||||||
|
if (pPrimarySurfDesc) {
|
||||||
|
g_system->copyRectToScreen(pPrimarySurfDesc->vidPtr, 320, 0, 0, 320, 200);
|
||||||
|
g_system->updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
time = util_getTimeKey() - startFrameTime;
|
||||||
|
if (time > 1000 || time < 0) {
|
||||||
|
startFrameTime = util_getTimeKey();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (timer_enabled) {
|
||||||
|
do {
|
||||||
|
time = util_getTimeKey();
|
||||||
|
|
||||||
|
} while (time - startFrameTime < frameWaitTime);
|
||||||
|
} else {
|
||||||
|
if (frameWaitTime - time > 0)
|
||||||
|
util_delay(frameWaitTime - time);
|
||||||
|
}
|
||||||
|
startFrameTime = util_getTimeKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 joy_getState() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 joy_calibrate() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FontDesc *util_loadFont(const char *path) {
|
||||||
|
FontDesc *fontDesc = (FontDesc *) malloc(sizeof(FontDesc));
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
if (fontDesc == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
data = data_getData(path);
|
||||||
|
if (data == 0) {
|
||||||
|
free((char *)fontDesc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fontDesc->dataPtr = data + 4;
|
||||||
|
fontDesc->itemWidth = data[0] & 0x7f;
|
||||||
|
fontDesc->itemHeight = data[1];
|
||||||
|
fontDesc->startItem = data[2];
|
||||||
|
fontDesc->endItem = data[3];
|
||||||
|
|
||||||
|
fontDesc->itemSize =
|
||||||
|
((fontDesc->itemWidth - 1) / 8 + 1) * fontDesc->itemHeight;
|
||||||
|
fontDesc->bitWidth = fontDesc->itemWidth;
|
||||||
|
|
||||||
|
if (data[0] & 0x80)
|
||||||
|
fontDesc->extraData =
|
||||||
|
data + 4 + fontDesc->itemSize * (fontDesc->endItem -
|
||||||
|
fontDesc->startItem + 1);
|
||||||
|
else
|
||||||
|
fontDesc->extraData = 0;
|
||||||
|
return fontDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_freeFont(FontDesc * fontDesc) {
|
||||||
|
free(fontDesc->dataPtr - 4);
|
||||||
|
free((char *)fontDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_clearPalette(void) {
|
||||||
|
int16 i;
|
||||||
|
byte colors[768];
|
||||||
|
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
error("util_clearPalette: Video mode 0x%x is not supported!",
|
||||||
|
videoMode);
|
||||||
|
|
||||||
|
if (setAllPalette) {
|
||||||
|
for (i = 0; i < 768; i++)
|
||||||
|
colors[i] = 0;
|
||||||
|
g_system->setPalette(colors, 0, 256);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
vid_setPalElem(i, 0, 0, 0, 0, videoMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_insertStr(char *str1, char *str2, int16 pos) {
|
||||||
|
int16 len1;
|
||||||
|
int16 i;
|
||||||
|
int16 from;
|
||||||
|
|
||||||
|
i = strlen(str2);
|
||||||
|
len1 = strlen(str1);
|
||||||
|
if (pos < i)
|
||||||
|
from = pos;
|
||||||
|
else
|
||||||
|
from = i;
|
||||||
|
|
||||||
|
for (; i >= from; i--)
|
||||||
|
str2[len1 + i] = str2[i];
|
||||||
|
|
||||||
|
for (i = 0; i < len1; i++)
|
||||||
|
str2[i + from] = str1[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_cutFromStr(char *str, int16 from, int16 cutlen) {
|
||||||
|
int16 len;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
log_write("util_cutFromStr: str = %s, ", str);
|
||||||
|
len = strlen(str);
|
||||||
|
if (from >= len)
|
||||||
|
return;
|
||||||
|
if (from + cutlen > len) {
|
||||||
|
str[from] = 0;
|
||||||
|
log_write("res = %s\n", str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = from;
|
||||||
|
do {
|
||||||
|
str[i] = str[i + cutlen];
|
||||||
|
i++;
|
||||||
|
} while (str[i] != 0);
|
||||||
|
log_write("res = %s\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 util_strstr(const char *str1, char *str2) {
|
||||||
|
char c;
|
||||||
|
int16 len1;
|
||||||
|
int16 i;
|
||||||
|
|
||||||
|
log_write("util_strstr: str1 = %s, str2 = %s\n", str1, str2);
|
||||||
|
|
||||||
|
for (i = 0, len1 = strlen(str1); strlen(str2 + i) >= len1; i++) {
|
||||||
|
c = str2[i + len1];
|
||||||
|
str2[i + len1] = 0;
|
||||||
|
if (strcmp(str2 + i, str1) == 0) {
|
||||||
|
str2[i + len1] = c;
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
str2[i + len1] = c;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_listInsertFront(Util_List * list, void *data) {
|
||||||
|
Util_ListNode *node;
|
||||||
|
|
||||||
|
node = (Util_ListNode *) malloc(sizeof(Util_ListNode));
|
||||||
|
if (list->pHead != 0) {
|
||||||
|
node->pData = data;
|
||||||
|
node->pNext = list->pHead;
|
||||||
|
node->pPrev = 0;
|
||||||
|
list->pHead->pPrev = node;
|
||||||
|
list->pHead = node;
|
||||||
|
} else {
|
||||||
|
list->pHead = node;
|
||||||
|
list->pTail = node;
|
||||||
|
node->pData = data;
|
||||||
|
node->pNext = 0;
|
||||||
|
node->pPrev = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_listInsertBack(Util_List * list, void *data) {
|
||||||
|
Util_ListNode *node;
|
||||||
|
|
||||||
|
if (list->pHead != 0) {
|
||||||
|
if (list->pTail == 0) {
|
||||||
|
list->pTail = list->pHead;
|
||||||
|
log_write("util_listInsertBack: Broken list!");
|
||||||
|
}
|
||||||
|
|
||||||
|
node =
|
||||||
|
(Util_ListNode *) malloc(sizeof(Util_ListNode));
|
||||||
|
node->pData = data;
|
||||||
|
node->pPrev = list->pTail;
|
||||||
|
node->pNext = 0;
|
||||||
|
list->pTail->pNext = node;
|
||||||
|
list->pTail = node;
|
||||||
|
} else {
|
||||||
|
util_listInsertFront(list, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_listDropFront(Util_List * list) {
|
||||||
|
if (list->pHead->pNext == 0) {
|
||||||
|
free((char *)(list->pHead));
|
||||||
|
list->pHead = 0;
|
||||||
|
list->pTail = 0;
|
||||||
|
} else {
|
||||||
|
list->pHead = list->pHead->pNext;
|
||||||
|
free((char *)(list->pHead->pPrev));
|
||||||
|
list->pHead->pPrev = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_deleteList(Util_List * list) {
|
||||||
|
while (list->pHead != 0) {
|
||||||
|
util_listDropFront(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char *)list);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *util_str1 =
|
||||||
|
" ' + - :0123456789: <=> abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ";
|
||||||
|
char *util_str2 =
|
||||||
|
" ueaaaaceeeiii ooouu aioun ";
|
||||||
|
char *util_str3 = " ";
|
||||||
|
|
||||||
|
void util_prepareStr(char *str) {
|
||||||
|
int16 i;
|
||||||
|
int16 j;
|
||||||
|
char buf[300];
|
||||||
|
|
||||||
|
strcpy(buf, util_str1);
|
||||||
|
strcat(buf, util_str2);
|
||||||
|
strcat(buf, util_str3);
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(str); i++)
|
||||||
|
str[i] = buf[str[i] - 32];
|
||||||
|
|
||||||
|
while (str[0] == ' ')
|
||||||
|
util_cutFromStr(str, 0, 1);
|
||||||
|
|
||||||
|
while (strlen(str) > 0 && str[strlen(str) - 1] == ' ')
|
||||||
|
util_cutFromStr(str, strlen(str) - 1, 1);
|
||||||
|
|
||||||
|
i = util_strstr(" ", str);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (i == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (str[i] == ' ') {
|
||||||
|
util_cutFromStr(str, i - 1, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = util_strstr(" ", str + i);
|
||||||
|
if (j != 0)
|
||||||
|
i += j;
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void util_waitMouseRelease(char drawMouse) {
|
||||||
|
int16 buttons;
|
||||||
|
int16 mouseX;
|
||||||
|
int16 mouseY;
|
||||||
|
|
||||||
|
do {
|
||||||
|
game_checkKeys(&mouseX, &mouseY, &buttons, drawMouse);
|
||||||
|
if (drawMouse != 0)
|
||||||
|
draw_animateCursor(2);
|
||||||
|
} while (buttons != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_release(void) {;}
|
||||||
|
} // End of namespace Gob
|
68
gob/util.h
Normal file
68
gob/util.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __UTIL_H
|
||||||
|
#define __UTIL_H
|
||||||
|
|
||||||
|
#include "gob/video.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
struct Util_ListNode;
|
||||||
|
typedef struct Util_ListNode {
|
||||||
|
void *pData;
|
||||||
|
struct Util_ListNode *pNext;
|
||||||
|
struct Util_ListNode *pPrev;
|
||||||
|
} Util_ListNode;
|
||||||
|
|
||||||
|
typedef struct Util_List {
|
||||||
|
Util_ListNode *pHead;
|
||||||
|
Util_ListNode *pTail;
|
||||||
|
} Util_List;
|
||||||
|
|
||||||
|
void util_initInput(void);
|
||||||
|
void util_processInput(void);
|
||||||
|
void util_waitKey(void);
|
||||||
|
int16 util_getKey(void);
|
||||||
|
int16 util_checkKey(void);
|
||||||
|
int16 util_getRandom(int16 max);
|
||||||
|
void util_getMouseState(int16 *pX, int16 *pY, int16 *pButtons);
|
||||||
|
void util_setMousePos(int16 x, int16 y);
|
||||||
|
void util_delay(uint16 msecs);
|
||||||
|
void util_beep(int16 freq);
|
||||||
|
uint32 util_getTimeKey(void);
|
||||||
|
void util_waitMouseUp(void);
|
||||||
|
void util_waitMouseDown(void);
|
||||||
|
|
||||||
|
void keyboard_init(void);
|
||||||
|
void keyboard_release(void);
|
||||||
|
|
||||||
|
void util_clearPalette(void);
|
||||||
|
|
||||||
|
void asm_setPaletteBlock(char *tmpPalBuffer, int16 start, int16 end);
|
||||||
|
|
||||||
|
void vid_waitRetrace(int16 mode);
|
||||||
|
|
||||||
|
FontDesc *util_loadFont(const char *path);
|
||||||
|
void util_freeFont(FontDesc * fontDesc);
|
||||||
|
void util_clearPalette(void);
|
||||||
|
void util_insertStr(char *str1, char *str2, int16 pos);
|
||||||
|
void util_cutFromStr(char *str, int16 from, int16 cutlen);
|
||||||
|
int16 util_strstr(const char *str1, char *str2);
|
||||||
|
void util_waitEndFrame(void);
|
||||||
|
void util_setFrameRate(int16 rate);
|
||||||
|
|
||||||
|
void util_listInsertBack(Util_List * list, void *data);
|
||||||
|
void util_listInsertFront(Util_List * list, void *data);
|
||||||
|
void util_listDropFront(Util_List * list);
|
||||||
|
void util_deleteList(Util_List * list);
|
||||||
|
void util_prepareStr(char *str);
|
||||||
|
void util_waitMouseRelease(char drawMouse);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
547
gob/video.cpp
Normal file
547
gob/video.cpp
Normal file
|
@ -0,0 +1,547 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/video.h"
|
||||||
|
#include "gob/debug.h"
|
||||||
|
#include "gob/dataio.h"
|
||||||
|
|
||||||
|
#include "gob/driver_vga.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
VideoDriver *_videoDriver;
|
||||||
|
|
||||||
|
|
||||||
|
/* NOT IMPLEMENTED */
|
||||||
|
|
||||||
|
//XXX: Use this function to update the screen for now.
|
||||||
|
// This should be moved to a better location later on.
|
||||||
|
void vid_waitRetrace(int16) {
|
||||||
|
if (pPrimarySurfDesc) {
|
||||||
|
g_system->copyRectToScreen(pPrimarySurfDesc->vidPtr, 320, 0, 0, 320, 200);
|
||||||
|
g_system->updateScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char vid_initDriver(int16 vidMode) {
|
||||||
|
warning("STUB: vid_initDriver");
|
||||||
|
|
||||||
|
// FIXME: Finish all this stuff :)
|
||||||
|
g_system->initSize(320, 200);
|
||||||
|
|
||||||
|
_videoDriver = new VGAVideoDriver();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_freeDriver() {
|
||||||
|
delete _videoDriver;
|
||||||
|
warning("STUB: vid_freeDriver");
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 vid_getRectSize(int16 width, int16 height, int16 flag, int16 mode) {
|
||||||
|
int32 size;
|
||||||
|
|
||||||
|
if ((mode & 0x7f) != 0x13)
|
||||||
|
log_write
|
||||||
|
("vid_getRectSize: Warning! Video mode %d is not fully supported!\n",
|
||||||
|
mode & 0x7f);
|
||||||
|
switch (mode & 0x7f) {
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
size = ((int32)((width + 3) / 4)) * height * (flag + 1);
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
size = (int32)width *height;
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
|
size = ((int32)((width + 3) / 4)) * height * 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
size = ((int32)((width + 7) / 8)) * height * (flag + 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceDesc *vid_initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) {
|
||||||
|
char flagsAnd2;
|
||||||
|
byte *vidMem;
|
||||||
|
int32 sprSize;
|
||||||
|
int16 someFlags = 1;
|
||||||
|
SurfaceDesc *descPtr;
|
||||||
|
|
||||||
|
debug(0, "stub: vid_initSurfDesc()");
|
||||||
|
|
||||||
|
if (flags != PRIMARY_SURFACE)
|
||||||
|
sprAllocated++;
|
||||||
|
|
||||||
|
if (flags & RETURN_PRIMARY)
|
||||||
|
return pPrimarySurfDesc;
|
||||||
|
|
||||||
|
if (vidMode != 0x13)
|
||||||
|
error("vid_initSurfDesc: Only VGA 0x13 mode is supported!");
|
||||||
|
|
||||||
|
if ((flags & PRIMARY_SURFACE) == 0)
|
||||||
|
vidMode += 0x80;
|
||||||
|
|
||||||
|
if (flags & 2)
|
||||||
|
flagsAnd2 = 1;
|
||||||
|
else
|
||||||
|
flagsAnd2 = 0;
|
||||||
|
|
||||||
|
if (flags & PRIMARY_SURFACE) {
|
||||||
|
vidMem = 0;
|
||||||
|
primaryWidth = width;
|
||||||
|
mouseMaxCol = width;
|
||||||
|
primaryHeight = height;
|
||||||
|
mouseMaxRow = height;
|
||||||
|
sprSize = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
vidMem = 0;
|
||||||
|
sprSize = vid_getRectSize(width, height, flagsAnd2, vidMode);
|
||||||
|
if (flagsAnd2)
|
||||||
|
someFlags += 0x80;
|
||||||
|
}
|
||||||
|
if (flags & PRIMARY_SURFACE) {
|
||||||
|
descPtr = pPrimarySurfDesc;
|
||||||
|
vidMem = (byte *)malloc(320 * 200);
|
||||||
|
} else {
|
||||||
|
if (flags & DISABLE_SPR_ALLOC)
|
||||||
|
descPtr = (SurfaceDesc *)malloc(sizeof(SurfaceDesc));
|
||||||
|
else
|
||||||
|
descPtr = (SurfaceDesc *)malloc(sizeof(SurfaceDesc) + sprSize);
|
||||||
|
}
|
||||||
|
if (descPtr == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
descPtr->width = width;
|
||||||
|
descPtr->height = height;
|
||||||
|
descPtr->flag = someFlags;
|
||||||
|
descPtr->vidMode = vidMode;
|
||||||
|
if (vidMem == 0)
|
||||||
|
vidMem = ((byte *)descPtr) + sizeof(SurfaceDesc);
|
||||||
|
descPtr->vidPtr = vidMem;
|
||||||
|
|
||||||
|
descPtr->reserved1 = 0;
|
||||||
|
descPtr->reserved2 = 0;
|
||||||
|
return descPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_freeSurfDesc(SurfaceDesc * surfDesc) {
|
||||||
|
sprAllocated--;
|
||||||
|
if (surfDesc != pPrimarySurfDesc)
|
||||||
|
free((char *)surfDesc);
|
||||||
|
else
|
||||||
|
free(surfDesc->vidPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 vid_clampValue(int16 val, int16 max) {
|
||||||
|
if (val >= max)
|
||||||
|
val = max - 1;
|
||||||
|
|
||||||
|
if (val < 0)
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_drawSprite(SurfaceDesc *source, SurfaceDesc *dest,
|
||||||
|
int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
|
||||||
|
int16 temp;
|
||||||
|
int16 destRight;
|
||||||
|
int16 destBottom;
|
||||||
|
|
||||||
|
if (doRangeClamp) {
|
||||||
|
if (left > right) {
|
||||||
|
temp = left;
|
||||||
|
left = right;
|
||||||
|
right = temp;
|
||||||
|
}
|
||||||
|
if (top > bottom) {
|
||||||
|
temp = top;
|
||||||
|
top = bottom;
|
||||||
|
bottom = temp;
|
||||||
|
}
|
||||||
|
if (right < 0)
|
||||||
|
return;
|
||||||
|
if (bottom < 0)
|
||||||
|
return;
|
||||||
|
if (left >= source->width)
|
||||||
|
return;
|
||||||
|
if (top >= source->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (left < 0) {
|
||||||
|
x -= left;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
if (top < 0) {
|
||||||
|
y -= top;
|
||||||
|
top = 0;
|
||||||
|
}
|
||||||
|
right = vid_clampValue(right, source->width);
|
||||||
|
bottom = vid_clampValue(bottom, source->height);
|
||||||
|
if (right - left >= source->width)
|
||||||
|
right = left + source->width - 1;
|
||||||
|
if (bottom - top >= source->height)
|
||||||
|
bottom = top + source->height - 1;
|
||||||
|
|
||||||
|
if (x < 0) {
|
||||||
|
left -= x;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
if (y < 0) {
|
||||||
|
top -= y;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
if (left > right)
|
||||||
|
return;
|
||||||
|
if (top > bottom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (x >= dest->width)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (y >= dest->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
destRight = x + right - left;
|
||||||
|
destBottom = y + bottom - top;
|
||||||
|
if (destRight >= dest->width)
|
||||||
|
right -= destRight - dest->width + 1;
|
||||||
|
|
||||||
|
if (destBottom >= dest->height)
|
||||||
|
bottom -= destBottom - dest->height + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pDrawSprite(source, dest, left, top, right, bottom, x, y, transp);
|
||||||
|
_videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom,
|
||||||
|
int16 color) {
|
||||||
|
int16 temp;
|
||||||
|
|
||||||
|
if (doRangeClamp) {
|
||||||
|
if (left > right) {
|
||||||
|
temp = left;
|
||||||
|
left = right;
|
||||||
|
right = temp;
|
||||||
|
}
|
||||||
|
if (top > bottom) {
|
||||||
|
temp = top;
|
||||||
|
top = bottom;
|
||||||
|
bottom = temp;
|
||||||
|
}
|
||||||
|
if (right < 0)
|
||||||
|
return;
|
||||||
|
if (bottom < 0)
|
||||||
|
return;
|
||||||
|
if (left >= dest->width)
|
||||||
|
return;
|
||||||
|
if (top >= dest->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
left = vid_clampValue(left, dest->width);
|
||||||
|
top = vid_clampValue(top, dest->height);
|
||||||
|
right = vid_clampValue(right, dest->width);
|
||||||
|
bottom = vid_clampValue(bottom, dest->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pFillRect(dest, left, top, right, bottom, color);
|
||||||
|
_videoDriver->fillRect(dest, left, top, right, bottom, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, int16 color) {
|
||||||
|
if (x0 == x1 || y0 == y1) {
|
||||||
|
vid_fillRect(dest, x0, y0, x1, y1, color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pDrawLine(dest, x0, y0, x1, y1, color);
|
||||||
|
_videoDriver->drawLine(dest, x0, y0, x1, y1, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) {
|
||||||
|
if (x < 0 || y < 0 || x >= dest->width || y >= dest->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// pPutPixel(x, y, color, dest);
|
||||||
|
_videoDriver->putPixel(x, y, color, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_drawLetter(char item, int16 x, int16 y, FontDesc *fontDesc, int16 color1,
|
||||||
|
int16 color2, int16 transp, SurfaceDesc * dest) {
|
||||||
|
|
||||||
|
// pDrawLetter(item, x, y, fontDesc, color1, color2, transp, dest);
|
||||||
|
_videoDriver->drawLetter(item, x, y, fontDesc, color1, color2, transp, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_clearSurf(SurfaceDesc *dest) {
|
||||||
|
vid_fillRect(dest, 0, 0, dest->width - 1, dest->height - 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y,
|
||||||
|
int16 transp, SurfaceDesc *dest) {
|
||||||
|
|
||||||
|
if (vid_spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((dest->vidMode & 0x7f) != 0x13)
|
||||||
|
error("vid_drawPackedSprite: Vide mode 0x%x is not fully supported!",
|
||||||
|
dest->vidMode & 0x7f);
|
||||||
|
|
||||||
|
// pDrawPackedSprite(sprBuf, width, height, x, y, transp, dest);
|
||||||
|
_videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_setPalElem(int16 index, char red, char green, char blue, int16 unused,
|
||||||
|
int16 vidMode) {
|
||||||
|
byte pal[4];
|
||||||
|
|
||||||
|
redPalette[index] = red;
|
||||||
|
greenPalette[index] = green;
|
||||||
|
bluePalette[index] = blue;
|
||||||
|
|
||||||
|
if (vidMode != 0x13)
|
||||||
|
error("vid_setPalElem: Video mode 0x%x is not supported!",
|
||||||
|
vidMode);
|
||||||
|
|
||||||
|
pal[0] = red << 2;
|
||||||
|
pal[1] = green << 2;
|
||||||
|
pal[2] = blue << 2;
|
||||||
|
pal[3] = 0;
|
||||||
|
g_system->setPalette(pal, index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_setPalette(PalDesc *palDesc) {
|
||||||
|
int16 i;
|
||||||
|
byte pal[1024];
|
||||||
|
int16 numcolors;
|
||||||
|
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
error("vid_setPalette: Video mode 0x%x is not supported!",
|
||||||
|
videoMode);
|
||||||
|
|
||||||
|
if (setAllPalette)
|
||||||
|
numcolors = 256;
|
||||||
|
else
|
||||||
|
numcolors = 16;
|
||||||
|
|
||||||
|
for (i = 0; i < numcolors; i++) {
|
||||||
|
pal[i * 4 + 0] = palDesc->vgaPal[i].red << 2;
|
||||||
|
pal[i * 4 + 1] = palDesc->vgaPal[i].green << 2;
|
||||||
|
pal[i * 4 + 2] = palDesc->vgaPal[i].blue << 2;
|
||||||
|
pal[i * 4 + 3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_system->setPalette(pal, 0, numcolors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_setFullPalette(PalDesc *palDesc) {
|
||||||
|
Color *colors;
|
||||||
|
int16 i;
|
||||||
|
byte pal[1024];
|
||||||
|
|
||||||
|
if (setAllPalette) {
|
||||||
|
colors = palDesc->vgaPal;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
redPalette[i] = colors[i].red;
|
||||||
|
greenPalette[i] = colors[i].green;
|
||||||
|
bluePalette[i] = colors[i].blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
pal[i * 4 + 0] = colors[i].red << 2;
|
||||||
|
pal[i * 4 + 1] = colors[i].green << 2;
|
||||||
|
pal[i * 4 + 2] = colors[i].blue << 2;
|
||||||
|
pal[i * 4 + 3] = 0;
|
||||||
|
}
|
||||||
|
g_system->setPalette(pal, 0, 256);
|
||||||
|
} else {
|
||||||
|
vid_setPalette(palDesc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_initPrimary(int16 mode) {
|
||||||
|
int16 old;
|
||||||
|
if (curPrimaryDesc) {
|
||||||
|
vid_freeSurfDesc(curPrimaryDesc);
|
||||||
|
vid_freeSurfDesc(allocatedPrimary);
|
||||||
|
|
||||||
|
curPrimaryDesc = 0;
|
||||||
|
allocatedPrimary = 0;
|
||||||
|
}
|
||||||
|
if (mode != 0x13 && mode != 3 && mode != -1)
|
||||||
|
error("vid_initPrimary: Video mode 0x%x is not supported!",
|
||||||
|
mode);
|
||||||
|
|
||||||
|
if (videoMode != 0x13)
|
||||||
|
error("vid_initPrimary: Video mode 0x%x is not supported!",
|
||||||
|
mode);
|
||||||
|
|
||||||
|
old = oldMode;
|
||||||
|
if (mode == -1)
|
||||||
|
mode = 3;
|
||||||
|
|
||||||
|
oldMode = mode;
|
||||||
|
if (mode != 3)
|
||||||
|
vid_initDriver(mode);
|
||||||
|
|
||||||
|
needDriverInit = 1;
|
||||||
|
|
||||||
|
if (mode != 3) {
|
||||||
|
vid_initSurfDesc(mode, 320, 200, PRIMARY_SURFACE);
|
||||||
|
|
||||||
|
if (dontSetPalette)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vid_setFullPalette(pPaletteDesc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char vid_spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
|
||||||
|
int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) {
|
||||||
|
SurfaceDesc sourceDesc;
|
||||||
|
byte *memBuffer;
|
||||||
|
byte *srcPtr;
|
||||||
|
byte *destPtr;
|
||||||
|
byte *linePtr;
|
||||||
|
byte temp;
|
||||||
|
uint16 sourceLeft;
|
||||||
|
int16 curWidth;
|
||||||
|
int16 curHeight;
|
||||||
|
int16 offset;
|
||||||
|
int16 counter2;
|
||||||
|
uint16 cmdVar;
|
||||||
|
int16 bufPos;
|
||||||
|
int16 strLen;
|
||||||
|
|
||||||
|
warning("vid_spriteUncompressor called");
|
||||||
|
|
||||||
|
if ((destDesc->vidMode & 0x7f) != 0x13)
|
||||||
|
error("vid_spriteUncompressor: Video mode 0x%x is not supported!",
|
||||||
|
destDesc->vidMode & 0x7f);
|
||||||
|
|
||||||
|
if (sprBuf[0] != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sprBuf[1] != 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sprBuf[2] == 2) {
|
||||||
|
sourceDesc.width = srcWidth;
|
||||||
|
sourceDesc.height = srcHeight;
|
||||||
|
sourceDesc.vidMode = 0x93;
|
||||||
|
sourceDesc.vidPtr = sprBuf + 3;
|
||||||
|
vid_drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1,
|
||||||
|
srcHeight - 1, x, y, transp);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
memBuffer = (byte *)malloc(4114);
|
||||||
|
if (memBuffer == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
srcPtr = sprBuf + 3;
|
||||||
|
sourceLeft = READ_LE_UINT16(srcPtr);
|
||||||
|
|
||||||
|
destPtr = destDesc->vidPtr + destDesc->width * y + x;
|
||||||
|
|
||||||
|
curWidth = 0;
|
||||||
|
curHeight = 0;
|
||||||
|
|
||||||
|
linePtr = destPtr;
|
||||||
|
srcPtr += 4;
|
||||||
|
|
||||||
|
for (offset = 0; offset < 4078; offset++)
|
||||||
|
memBuffer[offset] = 0x20;
|
||||||
|
|
||||||
|
cmdVar = 0;
|
||||||
|
bufPos = 4078;
|
||||||
|
while (1) {
|
||||||
|
cmdVar >>= 1;
|
||||||
|
if ((cmdVar & 0x100) == 0) {
|
||||||
|
cmdVar = *srcPtr | 0xff00;
|
||||||
|
srcPtr++;
|
||||||
|
}
|
||||||
|
if ((cmdVar & 1) != 0) {
|
||||||
|
temp = *srcPtr++;
|
||||||
|
if (temp != 0 || transp == 0)
|
||||||
|
*destPtr = temp;
|
||||||
|
destPtr++;
|
||||||
|
curWidth++;
|
||||||
|
if (curWidth >= srcWidth) {
|
||||||
|
curWidth = 0;
|
||||||
|
linePtr += destDesc->width;
|
||||||
|
destPtr = linePtr;
|
||||||
|
curHeight++;
|
||||||
|
if (curHeight >= srcHeight)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sourceLeft--;
|
||||||
|
if (sourceLeft == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
memBuffer[bufPos] = temp;
|
||||||
|
bufPos++;
|
||||||
|
bufPos %= 4096;
|
||||||
|
} else {
|
||||||
|
offset = *srcPtr;
|
||||||
|
srcPtr++;
|
||||||
|
offset |= (*srcPtr & 0xf0) << 4;
|
||||||
|
strLen = (*srcPtr & 0x0f) + 3;
|
||||||
|
srcPtr++;
|
||||||
|
|
||||||
|
for (counter2 = 0; counter2 < strLen;
|
||||||
|
counter2++) {
|
||||||
|
temp =
|
||||||
|
memBuffer[(offset +
|
||||||
|
counter2) % 4096];
|
||||||
|
if (temp != 0 || transp == 0)
|
||||||
|
*destPtr = temp;
|
||||||
|
destPtr++;
|
||||||
|
|
||||||
|
curWidth++;
|
||||||
|
if (curWidth >= srcWidth) {
|
||||||
|
curWidth = 0;
|
||||||
|
linePtr += destDesc->width;
|
||||||
|
destPtr = linePtr;
|
||||||
|
curHeight++;
|
||||||
|
if (curHeight >= srcHeight) {
|
||||||
|
free(memBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceLeft--;
|
||||||
|
if (sourceLeft == 0) {
|
||||||
|
free(memBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memBuffer[bufPos] = temp;
|
||||||
|
bufPos++;
|
||||||
|
bufPos %= 4096;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(memBuffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vid_setHandlers() {
|
||||||
|
//pDrawPacked = &vid_spriteUncompressor;
|
||||||
|
pFileHandler = 0;
|
||||||
|
setAllPalette = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
125
gob/video.h
Normal file
125
gob/video.h
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
** Gobliiins 1
|
||||||
|
** Original game by CoktelVision
|
||||||
|
**
|
||||||
|
** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
#ifndef __VIDEO_H
|
||||||
|
#define __VIDEO_H
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#define VID_SET_CURSOR(val) { _AH = 1; _CX = (val); geninterrupt(0x10); }
|
||||||
|
#define VID_RESTORE_MODE { _AX = 3; geninterrupt(0x10); }
|
||||||
|
|
||||||
|
#define TEXT_VID_SEG 0xB800
|
||||||
|
#define TEXT_VID_OFF 0
|
||||||
|
#define TEXT_COL_COUNT 80
|
||||||
|
#define TEXT_ROW_COUNT 25
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SurfaceDesc_t {
|
||||||
|
int16 width;
|
||||||
|
int16 height;
|
||||||
|
char reserved1;
|
||||||
|
char flag;
|
||||||
|
int16 vidMode;
|
||||||
|
byte *vidPtr;
|
||||||
|
int16 reserved2;
|
||||||
|
} SurfaceDesc;
|
||||||
|
|
||||||
|
typedef struct FontDesc_t {
|
||||||
|
char *dataPtr;
|
||||||
|
char itemWidth;
|
||||||
|
char itemHeight;
|
||||||
|
char startItem;
|
||||||
|
char endItem;
|
||||||
|
char itemSize;
|
||||||
|
char bitWidth;
|
||||||
|
void *extraData;
|
||||||
|
} FontDesc;
|
||||||
|
|
||||||
|
|
||||||
|
class VideoDriver {
|
||||||
|
public:
|
||||||
|
VideoDriver() {}
|
||||||
|
virtual ~VideoDriver() {}
|
||||||
|
virtual void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0;
|
||||||
|
virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0;
|
||||||
|
virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) = 0;
|
||||||
|
virtual void drawLetter(char item, int16 x, int16 y, FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc *dest) = 0;
|
||||||
|
virtual void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0;
|
||||||
|
virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc *dest) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*FillRectFunc) (SurfaceDesc * desc, int16 left, int16 top, int16 right,
|
||||||
|
int16 bottom, int16 color);
|
||||||
|
typedef void (*DrawSpriteFunc) (SurfaceDesc * source, SurfaceDesc * dest,
|
||||||
|
int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp);
|
||||||
|
typedef void (*PutPixelFunc) (int16 x, int16 y, int16 color, SurfaceDesc * desc);
|
||||||
|
typedef void (*XorRectFunc) (SurfaceDesc * desc, int16 left, int16 top, int16 right,
|
||||||
|
int16 bottom);
|
||||||
|
typedef void (*SetXorValFunc) (int16 val);
|
||||||
|
typedef void (*DrawLineFunc) (SurfaceDesc * desc, int16 x0, int16 y0, int16 x1,
|
||||||
|
int16 y1, int16 color);
|
||||||
|
typedef void (*DrawLetterFunc) (char item, int16 x, int16 y, FontDesc * fontDesc,
|
||||||
|
int16 color1, int16 color2, int16 transp, SurfaceDesc * dest);
|
||||||
|
typedef char (*DrawPackedSpriteFunc) (byte *sprBuf, int16 width, int16 height,
|
||||||
|
int16 x, int16 y, int16 transp, SurfaceDesc * dest);
|
||||||
|
|
||||||
|
#define GDR_VERSION 4
|
||||||
|
|
||||||
|
#define SET_SEG(ptr,seg) (((unsigned*)(ptr))[1] = (seg))
|
||||||
|
|
||||||
|
|
||||||
|
#define PRIMARY_SURFACE 0x80
|
||||||
|
#define RETURN_PRIMARY 0x01
|
||||||
|
#define DISABLE_SPR_ALLOC 0x20
|
||||||
|
|
||||||
|
typedef struct Color {
|
||||||
|
byte red;
|
||||||
|
byte green;
|
||||||
|
byte blue;
|
||||||
|
} Color;
|
||||||
|
|
||||||
|
typedef struct PalDesc {
|
||||||
|
Color *vgaPal;
|
||||||
|
int16 *unused1;
|
||||||
|
int16 *unused2;
|
||||||
|
} PalDesc;
|
||||||
|
|
||||||
|
char vid_initDriver(int16 vidMode);
|
||||||
|
void vid_freeDriver(void);
|
||||||
|
int32 vid_getRectSize(int16 width, int16 height, int16 flag, int16 mode);
|
||||||
|
SurfaceDesc *vid_initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags);
|
||||||
|
void vid_freeSurfDesc(SurfaceDesc * surfDesc);
|
||||||
|
int16 vid_clampValue(int16 val, int16 max);
|
||||||
|
void vid_drawSprite(SurfaceDesc * source, SurfaceDesc * dest, int16 left,
|
||||||
|
int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp);
|
||||||
|
void vid_fillRect(SurfaceDesc * dest, int16 left, int16 top, int16 right, int16 bottom,
|
||||||
|
int16 color);
|
||||||
|
void vid_drawLine(SurfaceDesc * dest, int16 x0, int16 y0, int16 x1, int16 y1,
|
||||||
|
int16 color);
|
||||||
|
void vid_putPixel(int16 x, int16 y, int16 color, SurfaceDesc * dest);
|
||||||
|
void vid_drawLetter(char item, int16 x, int16 y, FontDesc * fontDesc, int16 color1,
|
||||||
|
int16 color2, int16 transp, SurfaceDesc * dest);
|
||||||
|
void vid_clearSurf(SurfaceDesc * dest);
|
||||||
|
void vid_drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y,
|
||||||
|
int16 transp, SurfaceDesc * dest);
|
||||||
|
void vid_setPalElem(int16 index, char red, char green, char blue, int16 unused,
|
||||||
|
int16 vidMode);
|
||||||
|
void vid_setPalette(PalDesc * palDesc);
|
||||||
|
void vid_setFullPalette(PalDesc * palDesc);
|
||||||
|
void vid_initPrimary(int16 mode);
|
||||||
|
char vid_spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x,
|
||||||
|
int16 y, int16 transp, SurfaceDesc * destDesc);
|
||||||
|
void vid_setHandlers(void);
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue