Commit 4c459787 authored by alistert's avatar alistert

Created look-up tables for trigonometric functions. Refactored sprite loading....

Created look-up tables for trigonometric functions. Refactored sprite loading. Added sprites to bonus levels.
parent 147bdfc9
......@@ -189,7 +189,11 @@ typedef int fixed;
// Variable
// Time
EXTERN unsigned int globalTicks;
EXTERN unsigned int globalTicks;
// Trigonometric function look-up tables
EXTERN fixed sinLut[1024];
EXTERN fixed tanLut[1024];
// Functions in main.cpp
......@@ -209,7 +213,10 @@ EXTERN char * createEditableString (const char *string);
EXTERN void log (const char *message);
EXTERN void log (const char *message, const char *detail);
EXTERN void log (const char *message, int number);
EXTERN void logError (const char *message, const char *detail);
EXTERN void logError (const char *message, const char *detail);
EXTERN fixed fSin (fixed angle);
EXTERN fixed fCos (fixed angle);
EXTERN fixed fTan (fixed angle);
#ifdef VERBOSE
#define LOG(x, y) log(x, y)
......
......@@ -28,7 +28,10 @@
#include "game/game.h"
#include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h"
#include "io/gfx/sprite.h"
#include "io/gfx/video.h"
#include "io/sound.h"
#include "player/player.h"
#include "baselevel.h"
......@@ -48,6 +51,27 @@ BaseLevel::BaseLevel () {
}
BaseLevel::~BaseLevel () {
stopMusic();
// Free the palette effects
if (paletteEffects) {
delete paletteEffects;
paletteEffects = NULL;
}
SDL_FreeSurface(tileSet);
delete[] spriteSet;
return;
}
void BaseLevel::timeCalcs () {
// Calculate smoothed fps
......
......@@ -55,11 +55,16 @@ enum LevelStage {
// Classes
class File;
class Sprite;
class BaseLevel {
protected:
SDL_Surface* tileSet;
Sprite* spriteSet;
SDL_Color palette[256];
int sprites;
unsigned int tickOffset, prevStepTicks, prevTicks, ticks;
unsigned int endTime;
float smoothfps;
......@@ -71,7 +76,8 @@ class BaseLevel {
void drawStats (int stats, unsigned char bg);
public:
BaseLevel ();
BaseLevel ();
~BaseLevel ();
void addTimer ();
......
......@@ -33,21 +33,92 @@
#include "io/file.h"
#include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h"
#include "io/gfx/sprite.h"
#include "io/gfx/video.h"
#include "io/sound.h"
#include "menu/menu.h"
#include "player/player.h"
#include <math.h>
#include <string.h>
#ifdef __SYMBIAN32__
extern float cosf (float);
extern float sinf (float);
extern float tanf (float);
#endif
#define PI 3.141592f
int Bonus::loadSprites () {
File *file;
unsigned char* pixels;
int pos, maskLength, pixelsLength;
int width, height;
int count;
try {
file = new File(F_BONUS, false);
} catch (int e) {
return e;
}
file->seek(2, true);
sprites = file->loadShort();
spriteSet = new Sprite[sprites];
for (count = 0; count < sprites; count++) {
spriteSet[count].xOffset = 0;
spriteSet[count].yOffset = 0;
// Load dimensions
width = file->loadShort();
height = file->loadShort();
pixelsLength = file->loadShort();
maskLength = file->loadShort();
// Sprites can be either masked or not masked.
if (pixelsLength != 0xFFFF) {
// Masked
width <<= 2;
pos = file->tell() + (pixelsLength << 2) + maskLength;
// Read scrambled, masked pixel data
pixels = file->loadPixels(width * height, 0);
spriteSet[count].setPixels(pixels, width, height, 0);
delete[] pixels;
file->seek(pos, true);
} else if (width) {
// Not masked
// Read pixel data
pixels = file->loadBlock(width * height);
spriteSet[count].setPixels(pixels, width, height, 0);
delete[] pixels;
} else {
// Zero-length sprite
// Create blank sprite
spriteSet[count].clearPixels();
}
}
delete file;
return E_NONE;
}
int Bonus::loadTiles (char *fileName) {
......@@ -118,7 +189,7 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
unsigned char *buffer;
char *string, *fileString;
int x, y;
try {
file = new File(fileName, false);
......@@ -129,6 +200,9 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
}
// Load sprites
loadSprites();
// Load tileset
......@@ -238,8 +312,9 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
paletteEffects = new RotatePaletteEffect(240, 16, F32, paletteEffects);
// Adjust fontsFont to use bonus level palette
// Adjust fonts to use bonus level palette
fontsFont->mapPalette(0, 32, 15, -16);
panelBigFont->mapPalette(0, 32, 15, -16);
return;
......@@ -248,18 +323,10 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
Bonus::~Bonus () {
// Free the palette effects
if (paletteEffects) {
delete paletteEffects;
paletteEffects = NULL;
}
SDL_FreeSurface(tileSet);
// Restore font palettes
fontsFont->restorePalette();
panelBigFont->restorePalette();
return;
......@@ -371,17 +438,18 @@ int Bonus::step () {
void Bonus::draw () {
unsigned char* row;
Sprite *sprite;
SDL_Rect dst;
fixed playerX, playerY, playerSin, playerCos;
fixed distance, opposite, adjacent;
fixed distance, opposite, adjacent, nX;
int levelX, levelY;
int spriteW, spriteH;
int x, y;
// Draw the background
for (x = -(localPlayer->getDirection() & 1023); x < canvasW; x += background->w) {
for (x = -(direction & 1023); x < canvasW; x += background->w) {
dst.x = x;
dst.y = (canvasH >> 1) - 4;
......@@ -400,28 +468,29 @@ void Bonus::draw () {
playerX = localPlayer->getX();
playerY = localPlayer->getY();
playerSin = fixed(1024.0f * sinf(PI * float(direction) / 512.0f));
playerCos = fixed(1024.0f * cosf(PI * float(direction) / 512.0f));
playerSin = fSin(direction);
playerCos = fCos(direction);
if (SDL_MUSTLOCK(canvas)) SDL_LockSurface(canvas);
for (y = 1; y <= (canvasH >> 1) - 15; y++) {
distance = fixed(1024.0f * tanf((float(y) / float(canvasH >> 1)) + ((PI / 2.0f) - 1.0f)) * 20.0f);
distance = fTan((y * 512 / ((canvasH * 3) >> 1)) + 93) * 20;
opposite = MUL(distance, playerSin);
adjacent = MUL(distance, playerCos);
row = ((unsigned char *)(canvas->pixels)) + (canvas->pitch * (canvasH - y));
for (x = 0; x < canvasW; x++) {
fixed nX = ITOF(x - (canvasW >> 1)) / canvasW;
nX = (ITOF(x) / canvasW) - FH;
levelX = FTOI(playerX + opposite + MUL(nX, adjacent));
levelY = FTOI(playerY - adjacent + MUL(nX, opposite));
((unsigned char *)(canvas->pixels))[(canvas->pitch * (canvasH - y)) + x] =
((unsigned char *)(tileSet->pixels))
[(grid[ITOT(levelY) & 255][ITOT(levelX) & 255].tile * 1024) +
((levelY & 31) * tileSet->pitch) + (levelX & 31)];
row[x] = ((unsigned char *)(tileSet->pixels))
[(grid[ITOT(levelY) & 255][ITOT(levelX) & 255].tile << 10) +
((levelY & 31) * tileSet->pitch) + (levelX & 31)];
}
......@@ -430,66 +499,69 @@ void Bonus::draw () {
if (SDL_MUSTLOCK(canvas)) SDL_UnlockSurface(canvas);
// Draw the events
// Draw nearby events
for (y = -7; y < 8; y++) {
for (y = -6; y < 6; y++) {
fixed sY = TTOF(y) + F16 - (playerY & 32767);
fixed sY = TTOF(((direction - FQ) & 512)? y: -y) + F16 - (playerY & 32767);
for (x = -7; x < 8; x++) {
for (x = -6; x < 6; x++) {
fixed sX = TTOF(x) + F16 - (playerX & 32767);
fixed sX = TTOF((direction & 512)? x: -x) + F16 - (playerX & 32767);
fixed divisor = MUL(sX, playerSin) - MUL(sY, playerCos);
if (FTOI(divisor) > 0) {
spriteW = 1000 / FTOI(divisor);
spriteH = 1000 / FTOI(divisor);
fixed nX = DIV(MUL(sX, playerCos) + MUL(sY, playerSin), divisor);
dst.x = FTOI(nX * canvasW) + ((canvasW - spriteW) >> 1);
dst.y = (canvasH - spriteH) >> 1;
switch (grid[(y + FTOT(playerY)) & 255][(x + FTOT(playerX)) & 255].event) {
switch (grid[((((direction - FQ) & 512)? y: -y) + FTOT(playerY)) & 255][(((direction & 512)? x: -x) + FTOT(playerX)) & 255].event) {
case 0: // No event
sprite = NULL;
break;
case 1: // Extra time
drawRect(dst.x, dst.y, spriteW, spriteH, 60);
sprite = spriteSet + 46;
break;
case 2: // Gem
drawRect(dst.x, dst.y, spriteW, spriteH, 67);
sprite = spriteSet + 47;
break;
case 3: // Hand
drawRect(dst.x, dst.y, spriteW, spriteH, 15);
sprite = spriteSet + 48;
break;
case 4: // Exit
drawRect(dst.x, dst.y, spriteW, spriteH, 45);
sprite = spriteSet + 49;
break;
default:
drawRect(dst.x, dst.y, spriteW, spriteH, 0);
sprite = spriteSet + 14;
break;
}
if (sprite) {
nX = DIV(MUL(sX, playerCos) + MUL(sY, playerSin), divisor);
dst.x = FTOI(nX * canvasW) + ((canvasW - (ITOF(sprite->getWidth() << 5) / divisor)) >> 1);
dst.y = (canvasH - (ITOF(sprite->getHeight() << 5) / divisor)) >> 1;
sprite->drawScaled(dst.x, dst.y, DIV(F32, divisor));
}
}
}
......@@ -498,6 +570,7 @@ void Bonus::draw () {
// Show gem count
spriteSet[47].draw(0, 0);
fontsFont->showString("x", 15, 0);
fontsFont->showNumber(localPlayer->getItems(), 64, 0);
fontsFont->showNumber(items, 117, 0);
......
......@@ -57,10 +57,11 @@ class Bonus : public BaseLevel {
char mask[60][64]; // At most 60 tiles, all with 8 * 8 masks
fixed direction;
int loadTiles (char* fileName);
bool isEvent (fixed x, fixed y);
int step ();
void draw ();
int loadSprites ();
int loadTiles (char* fileName);
bool isEvent (fixed x, fixed y);
int step ();
void draw ();
public:
Bonus (char* fileName, unsigned char diff);
......
......@@ -321,6 +321,91 @@ SDL_Surface* File::loadSurface (int width, int height) {
}
unsigned char* File::loadPixels (int length) {
unsigned char* pixels;
unsigned char* sorted;
int count;
sorted = new unsigned char[length];
pixels = loadBlock(length);
// Rearrange pixels in correct order
for (count = 0; count < length; count++) {
sorted[count] = pixels[(count >> 2) + ((count & 3) * (length >> 2))];
}
delete[] pixels;
return sorted;
}
unsigned char* File::loadPixels (int length, int key) {
unsigned char* pixels;
unsigned char* sorted;
unsigned char mask;
int count;
sorted = new unsigned char[length];
pixels = new unsigned char[length];
// Read the mask
// Each mask pixel is either 0 or 1
// Four pixels are packed into the lower end of each byte
for (count = 0; count < length; count++) {
if (!(count & 3)) mask = fgetc(file);
pixels[count] = (mask >> (count & 3)) & 1;
}
// Pixels are loaded if the corresponding mask pixel is 1, otherwise
// the transparent index is used. Pixels are scrambled, so the mask
// has to be scrambled the same way.
for (count = 0; count < length; count++) {
sorted[(count >> 2) + ((count & 3) * (length >> 2))] = pixels[count];
}
// Read pixels according to the scrambled mask
for (count = 0; count < length; count++) {
// Use the transparent pixel
pixels[count] = key;
if (sorted[count] == 1) {
// The unmasked portions are transparent, so no masked
// portion should be transparent.
while (pixels[count] == key) pixels[count] = fgetc(file);
}
}
// Rearrange pixels in correct order
for (count = 0; count < length; count++) {
sorted[count] = pixels[(count >> 2) + ((count & 3) * (length >> 2))];
}
delete[] pixels;
return sorted;
}
void File::loadPalette (SDL_Color* palette) {
unsigned char* buffer;
......
......@@ -57,8 +57,10 @@ class File {
unsigned char* loadRLE (int length);
void skipRLE ();
char* loadString ();
SDL_Surface* loadSurface (int width, int height);
void loadPalette (SDL_Color *palette);
SDL_Surface* loadSurface (int width, int height);
unsigned char* loadPixels (int length);
unsigned char* loadPixels (int length, int key);
void loadPalette (SDL_Color* palette);
};
......
......@@ -165,7 +165,7 @@ Font::Font (unsigned char* pixels, bool big) {
characters[count] = createSurface(chrPixels, 8, lineHeight);
if (big) SDL_SetColorKey(characters[count], SDL_SRCCOLORKEY, 0);
if (big) SDL_SetColorKey(characters[count], SDL_SRCCOLORKEY, 31);
}
......@@ -212,7 +212,6 @@ Font::Font () {
File* file;
unsigned char* pixels;
unsigned char* sorted;
int fileSize;
int count, width, height;
......@@ -251,13 +250,11 @@ Font::Font () {
file->seek(4, false);
pixels = file->loadBlock(width * height);
sorted = sortPixels(pixels, width * height);
pixels = file->loadPixels(width * height);
characters[count] = createSurface(sorted, width, height);
characters[count] = createSurface(pixels, width, height);
SDL_SetColorKey(characters[count], SDL_SRCCOLORKEY, 254);
delete[] sorted;
delete[] pixels;
}
......
......@@ -49,28 +49,22 @@ void Sprite::clearPixels () {
if (pixels) SDL_FreeSurface(pixels);
data = SKEY;
data = 0;
pixels = createSurface(&data, 1, 1);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, SKEY);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, 0);
return;
}
void Sprite::setPixels (unsigned char *data, int width, int height) {
void Sprite::setPixels (unsigned char *data, int width, int height, unsigned char key) {
unsigned char *sorted;
if (pixels) SDL_FreeSurface(pixels);
sorted = sortPixels(data, width * height);
pixels = createSurface(sorted, width, height);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, SKEY);
pixels = createSurface(data, width, height);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, key);
delete[] sorted;
return;
}
......@@ -139,3 +133,74 @@ void Sprite::draw (int x, int y) {
}
void Sprite::drawScaled (int x, int y, fixed scale) {
unsigned char* srcRow;
unsigned char* dstRow;
unsigned char pixel, key;
int width, height;
int dstX, dstY;
int srcX, srcY;
key = pixels->format->colorkey;
width = FTOI(pixels->w * scale);
if (x + width > canvasW) width = canvasW - x;
if (x < -width) return; // Off-screen
height = FTOI(pixels->h * scale);
if (y + height > canvasH) height = canvasH - y;
if (y < -height) return; // Off-screen
if (SDL_MUSTLOCK(canvas)) SDL_LockSurface(canvas);
if (y < 0) {
srcY = -y;
dstY = 0;
} else {
srcY = 0;
dstY = y;
}
while (srcY < height) {
srcRow = ((unsigned char *)(pixels->pixels)) + (pixels->pitch * DIV(srcY, scale));
dstRow = ((unsigned char *)(canvas->pixels)) + (canvas->pitch * dstY);
if (x < 0) {
srcX = -x;
dstX = 0;
} else {
srcX = 0;
dstX = x;
}
while (srcX < width) {
pixel = srcRow[DIV(srcX, scale)];
if (pixel != key) dstRow[dstX] = pixel;
srcX++;
dstX++;
}
srcY++;
dstY++;
}
if (SDL_MUSTLOCK(canvas)) SDL_UnlockSurface(canvas);
return;
}
......@@ -28,11 +28,6 @@
#include <SDL/SDL.h>
// Constant
#define SKEY 254 /* Sprite colour key */
// Class
class Sprite {
......@@ -48,10 +43,11 @@ class Sprite {
~Sprite ();
void clearPixels ();
void setPixels (unsigned char* data, int width, int height);
void setPixels (unsigned char* data, int width, int height, unsigned char key);
int getWidth ();
int getHeight ();
void draw (int x, int y);
void drawScaled (int x, int y, fixed scale);
void setPalette (SDL_Color* palette, int start, int amount);
void flashPalette (int index);
void restorePalette ();
......
......@@ -36,25 +36,6 @@
#include <string.h>
unsigned char * sortPixels (unsigned char * pixels, int length) {
unsigned char *sorted;
int count;
sorted = new unsigned char[length];
// Rearrange pixels in correct order
for (count = 0; count < length; count++) {
sorted[count] = pixels[(count >> 2) + ((count & 3) * (length >> 2))];
}
return sorted;
}
SDL_Surface* createSurface (unsigned char * pixels, int width, int height) {
SDL_Surface *ret;
......
......@@ -111,7 +111,6 @@ EXTERN Video video;
// Functions
EXTERN unsigned char* sortPixels (unsigned char* pixels, int length);
EXTERN SDL_Surface* createSurface (unsigned char* pixels, int width, int height);
EXTERN void clearScreen (int index);
EXTERN void drawRect (int x, int y, int width, int height, int index);
......
......@@ -40,8 +40,6 @@
#include "io/sound.h"
#include "player/player.h"
#include <math.h>
Event::Event () {
......
......@@ -34,8 +34,8 @@
#include "io/gfx/video.h"
#include "io/sound.h"
#include "player/player.h"
#include <math.h>
#include <stdlib.h>
signed char* Event::prepareStep (unsigned int ticks, int msps) {
......@@ -86,8 +86,8 @@ Event* Event::step (unsigned int ticks, int msps) {
fixed width, height;
signed char* set;
int count;
fixed offset;
float angle;
int offset;
fixed angle;
set = prepareStep(ticks, msps);
......@@ -305,11 +305,11 @@ Event* Event::step (unsigned int ticks, int msps) {
// Rotate
offset = ITOF(set[E_BRIDGELENGTH] * set[E_CHAINLENGTH]);
angle = set[E_MAGNITUDE] * ticks / 2048.0f;
offset = set[E_BRIDGELENGTH] * set[E_CHAINLENGTH];
angle = set[E_MAGNITUDE] * ticks / 13;
dx = TTOF(gridX) + (int)(sin(angle) * offset) - x;
dy = TTOF(gridY) + (int)((cos(angle) + 1.0f) * offset) - y;
dx = TTOF(gridX) + (fSin(angle) * offset) - x;
dy = TTOF(gridY) + ((fCos(angle) + F1) * offset) - y;
dx = ((dx << 10) / msps) * set[E_MOVEMENTSP];
dy = ((dy << 10) / msps) * set[E_MOVEMENTSP];
......@@ -319,12 +319,11 @@ Event* Event::step (unsigned int ticks, int msps) {
// Swing
offset = ITOF(set[E_BRIDGELENGTH] * set[E_CHAINLENGTH]);
angle = (set[E_CHAINANGLE] * 3.141592f / 128.0f) +
(set[E_MAGNITUDE] * ticks / 2048.0f);
offset = set[E_BRIDGELENGTH] * set[E_CHAINLENGTH];
angle = (set[E_CHAINANGLE] << 2) + (set[E_MAGNITUDE] * ticks / 13);
dx = TTOF(gridX) + (int)(sin(angle) * offset) - x;
dy = TTOF(gridY) + (int)((fabs(cos(angle)) + 1.0f) * offset) - y;
dx = TTOF(gridX) + (fSin(angle) * offset) - x;
dy = TTOF(gridY) + ((abs(fCos(angle)) + F1) * offset) - y;
dx = ((dx << 10) / msps) * set[E_MOVEMENTSP];
dy = ((dy << 10) / msps) * set[E_MOVEMENTSP];
......
......@@ -87,18 +87,6 @@ Level::~Level () {
int count;
// Free all data
stopMusic();
// Free the palette effects
if (paletteEffects) {
delete paletteEffects;
paletteEffects = NULL;
}
// Free events
if (events) delete events;
......@@ -112,10 +100,6 @@ Level::~Level () {
}
SDL_FreeSurface(tileSet);
delete[] spriteSet;
delete[] sceneFile;
return;
......
......@@ -93,7 +93,6 @@ class Level : public BaseLevel {
private:
char* sceneFile;
Sprite* spriteSet; // 208 of which are usually in mainchar.000
Anim animSet[ANIMS];
char miscAnims[4];
signed char bulletSet[BULLETS][BLENGTH];
......@@ -104,7 +103,6 @@ class Level : public BaseLevel {
SDL_Color skyPalette[256];
bool sky;
unsigned char skyOrb;
int sprites;
int levelNum, worldNum, nextLevelNum, nextWorldNum;
unsigned char difficulty;
int enemies;
......@@ -113,8 +111,9 @@ class Level : public BaseLevel {
fixed waterLevelSpeed;
fixed energyBar;
int loadSprites (char* fileName);
int loadTiles (char* fileName);
void loadSprite (File* file, Sprite* sprite);
int loadSprites (char* fileName);
int loadTiles (char* fileName);
protected:
int load (char* fileName, unsigned char diff, bool checkpoint);
......
......@@ -47,12 +47,70 @@
#include <string.h>
#define SKEY 254 /* Sprite colour key */
void Level::loadSprite (File* file, Sprite* sprite) {
unsigned char* pixels;
int pos, maskOffset;
int width, height;
// Load dimensions
width = file->loadShort() << 2;
height = file->loadShort();
file->seek(2, false);
maskOffset = file->loadShort();
pos = file->loadShort() << 2;
// Sprites can be either masked or not masked.
if (maskOffset) {
// Masked
height++;
// Skip to mask
file->seek(maskOffset, false);
// Find the end of the data
pos += file->tell() + ((width >> 2) * height);
// Read scrambled, masked pixel data
pixels = file->loadPixels(width * height, SKEY);
sprite->setPixels(pixels, width, height, SKEY);
delete[] pixels;
file->seek(pos, true);
} else if (width) {
// Not masked
// Read scrambled pixel data
pixels = file->loadPixels(width * height);
sprite->setPixels(pixels, width, height, SKEY);
delete[] pixels;
}
return;
}
int Level::loadSprites (char * fileName) {
File *file, *mainFile, *specFile;
unsigned char *pixels, *mask;
int mainPos, specPos;
int count, x, y, width, height, m;
File* mainFile = NULL;
File* specFile = NULL;
int count;
// Open fileName
try {
......@@ -92,188 +150,58 @@ int Level::loadSprites (char * fileName) {
// Read vertical offsets
for (count = 0; count < sprites; count++)
spriteSet[count].yOffset = specFile->loadChar();
// Find where the sprites start in fileName
specPos = specFile->tell();
// Find where the sprites start in mainchar.000
mainPos = 2;
// Skip to where the sprites start in mainchar.000
mainFile->seek(2, true);
// Loop through all the sprites to be loaded
for (count = 0; count < sprites; count++) {
// Go to the start of the current sprite or file indicator
specFile->seek(specPos, true);
mainFile->seek(mainPos, true);
/* If both fileName and mainchar.000 have file indicators, create a
blank sprite */
while ((specFile->loadChar() == 0xFF) &&
(mainFile->loadChar() == 0xFF)) {
// Go to the next sprite/file indicator
specFile->seek(1, false);
mainFile->seek(1, false);
// set the position of the next sprite/file indicators
specPos += 2;
mainPos += 2;
// Create a blank sprite
spriteSet[count].clearPixels();
count++;
}
// Return to the start of the sprite/file indicators
specFile->seek(specPos, true);
mainFile->seek(mainPos, true);
// Unless otherwise stated, load from fileName
file = specFile;
// Check if otherwise stated
if (file->loadChar() == 0xFF) {
file = mainFile;
} else file->seek(-1, false);
width = file->loadShort() << 2;
height = file->loadShort();
// Position of the next sprite or file indicator in each file
if (file == specFile) {
mainPos += 2;
specPos += 10 + (file->loadShort() << 2);
} else {
specPos += 2;
mainPos += 10 + (file->loadShort() << 2);
}
m = file->loadShort();
// Allocate space for mask
mask = new unsigned char[width * height];
// Actually, m is for mask offset.
// Sprites can be either masked or not masked.
if (!m) {
// Not masked
// Load the pixel data directly for descrambling
file->seek(2, false);
// Read pixel data
pixels = file->loadBlock(width * height);
} else {
// Allocate space for pixel data
pixels = new unsigned char[width * height];
// Masked
// Load the pixel data according to the mask
// Masked sprites have their own next sprite offsets
if (file == specFile) {
specPos = file->loadShort() << 2;
} else {
mainPos = file->loadShort() << 2;
}
// Skip to mask
file->seek(m, false);
// Read the mask
// Each mask pixel is either 0 or 1
// Four pixels are packed into the lower end of each byte
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
if (!(x & 3)) m = file->loadChar();
pixels[(y * width) + x] = (m >> (x & 3)) & 1;
}
}
// Pixels are loaded if the corresponding mask pixel is 1, otherwise
// the transparent index is used. Pixels are scrambled, so the mask
// has to be scrambled the same way.
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
mask[((y + ((x & 3) * height)) * (width >> 2)) + (x >> 2)] =
pixels[(y * width) + x];
}
}
// Skip to pixels
file->seek(width >> 2, false);
// Next sprite offsets are relative to here
if (file == specFile) specPos += file->tell();
else mainPos += file->tell();
// Read pixels according to the scrambled mask
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
if (mask[(y * width) + x] == 1) {
// The unmasked portions are transparent, so no masked
// portion should be transparent.
m = SKEY;
while (m == SKEY) m = file->loadChar();
// Use the acceptable pixel
pixels[(y * width) + x] = m;
} else {
// Use the transparent pixel
pixels[(y * width) + x] = SKEY;
}
}
if (specFile->loadChar() == 0xFF) {
// Go to the next sprite/file indicator
specFile->seek(1, false);
if (mainFile->loadChar() == 0xFF) {
}
// Go to the next sprite/file indicator
mainFile->seek(1, false);
/* Both fileName and mainchar.000 have file indicators, so
create a blank sprite */
spriteSet[count].clearPixels();
continue;
} else {
// Return to the start of the sprite
mainFile->seek(-1, false);
// Load the individual sprite data
loadSprite(mainFile, spriteSet + count);
}
} else {
// Return to the start of the sprite
specFile->seek(-1, false);
// Go to the main file's next sprite/file indicator
mainFile->seek(2, false);
// Load the individual sprite data
loadSprite(specFile, spriteSet + count);
}
// Convert the scrambled sprite to an SDL surface
spriteSet[count].setPixels(pixels, width, height);
// Free redundant data
delete[] pixels;
delete[] mask;
// Check if the next sprite exists
// If not, create blank sprites for the remainder
if (specPos >= file->getSize()) {
if (specFile->tell() >= specFile->getSize()) {
for (count++; count < sprites; count++) {
......@@ -281,10 +209,6 @@ int Level::loadSprites (char * fileName) {
}
} else {
specFile->seek(specPos, true);
}
}
......
......@@ -53,8 +53,16 @@
#ifdef __SYMBIAN32__
extern char KOpenJazzPath[256];
#endif
extern float cosf (float);
extern float sinf (float);
extern float tanf (float);
#else
#include <math.h>
#endif
#define PI 3.141592f
int loadMain (int argc, char *argv[]) {
......@@ -445,6 +453,15 @@ int loadMain (int argc, char *argv[]) {
// Establish arbitrary timing
globalTicks = SDL_GetTicks() - 20;
// Fill trigonomatric function look-up tables
for (count = 0; count < 1024; count++) {
sinLut[count] = fixed(sinf(2 * PI * float(count) / 1024.0f) * 1024.0f);
tanLut[count] = fixed(tanf(2 * PI * float(count) / 1024.0f) * 1024.0f);
}
// Initiate networking
net = new Network();
......
......@@ -38,8 +38,6 @@
#include "level/event/event.h"
#include "level/level.h"
#include <math.h>
void Player::control (unsigned int ticks, int msps) {
......@@ -673,8 +671,8 @@ void Player::bonusStep (unsigned int ticks, int msps, Bonus* bonus) {
// Apply trajectory
cdx = fixed(sin(direction * 6.283185f / 1024.0f) * dx * msps) >> 10;
cdy = fixed(-cos(direction * 6.283185f / 1024.0f) * dx * msps) >> 10;
cdx = (fSin(direction) * dx * msps) >> 20;
cdy = (-fCos(direction) * dx * msps) >> 20;
if (!bonus->checkMask(x + cdx, y)) x += cdx;
if (!bonus->checkMask(x, y + cdy)) y += cdy;
......@@ -800,8 +798,8 @@ void Player::draw (unsigned int ticks, int change) {
// Show invincibility stars
xOffset = (int)(sin(ticks / 100.0f) * F12);
yOffset = (int)(cos(ticks / 100.0f) * F12);
xOffset = fSin(ticks * 2) * 12;
yOffset = fCos(ticks * 2) * 12;
an = level->getMiscAnim(0);
......@@ -821,8 +819,8 @@ void Player::draw (unsigned int ticks, int change) {
// Show the 4-hit shield
xOffset = (int)(cos(ticks / 200.0f) * F20);
yOffset = (int)(sin(ticks / 200.0f) * F20);
xOffset = fCos(ticks) * 20;
yOffset = fSin(ticks) * 20;
an = level->getAnim(59);
......@@ -838,8 +836,8 @@ void Player::draw (unsigned int ticks, int change) {
// Show the 2-hit shield
xOffset = (int)(cos(ticks / 200.0f) * F20);
yOffset = (int)(sin(ticks / 200.0f) * F20);
xOffset = fCos(ticks) * 20;
yOffset = fSin(ticks) * 20;
an = level->getAnim(50);
......
......@@ -36,6 +36,9 @@
#include "io/gfx/video.h"
#include "io/sound.h"
#include <string.h>
SceneFrame::SceneFrame(int frameType, unsigned char* frameData, int frameSize) {
soundId = -1;
this->frameData = frameData;
......
......@@ -187,3 +187,23 @@ void logError (const char *message, const char *detail) {
}
fixed fSin (fixed angle) {
return sinLut[angle & 1023];
}
fixed fCos (fixed angle) {
return sinLut[(angle + 256) & 1023];
}
fixed fTan (fixed angle) {
return tanLut[angle & 1023];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment