[Scummvm-git-logs] scummvm master -> bfe16d0ed420992d2c9d42bedb0edeb8f483260e
salty-horse
ori at avtalion.name
Thu Feb 11 18:32:44 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
31e33a1e08 AGS: Convert to Unix newlines
bfe16d0ed4 AGS: Silence clang warnings
Commit: 31e33a1e08e8fc1a71edd6099170cca6a5c1f1db
https://github.com/scummvm/scummvm/commit/31e33a1e08e8fc1a71edd6099170cca6a5c1f1db
Author: Ori Avtalion (ori at avtalion.name)
Date: 2021-02-11T20:28:11+02:00
Commit Message:
AGS: Convert to Unix newlines
Changed paths:
engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
engines/ags/plugins/ags_pal_render/pal_render.h
engines/ags/plugins/ags_pal_render/raycast.cpp
engines/ags/plugins/ags_pal_render/raycast.h
diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
index d21fe61da3..6680a187d9 100644
--- a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
+++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
@@ -1,1849 +1,1849 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "ags/lib/allegro.h"
-#include "ags/plugins/ags_pal_render/ags_pal_render.h"
-#include "ags/plugins/ags_pal_render/pal_render.h"
-#include "ags/plugins/ags_pal_render/raycast.h"
-#include "ags/ags.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define MAX_OVERLAYS 128
-#define MAX_STARS 1024
-#define MAX_DEPTH 64
-
-#define PI (3.1415926535f)
-#define HALF_PI (0.5f * PI)
-#define TWO_PI (2.0f * PI)
-#define TWO_PI_INV (1.0f / TWO_PI)
-
-const float halfpi = (0.5f * PI);
-const float twopi = (2.0f * PI);
-const float twopi_inv = (1.0f / TWO_PI);
-const float pisquared = PI * PI;
-const float picubed = PI * PI * PI;
-
-IAGSEngine *engine;
-
-//unsigned char clut[256][256];
-unsigned char clut[65536];
-
-struct transoverlaytype {
- int sprite;
- int spritemask;
- int blendtype;
- int x;
- int y;
- int trans;
- int level;
- bool enabled;
-} overlay[MAX_OVERLAYS];
-
-int clutslot;
-int drawreflections;
-unsigned char cycle_remap [256];
-
-struct starstype {
- float x;
- float y;
- float z;
- unsigned char color;
- long sprite;
- int maxrad;
- int scaleboost;
-};
-starstype *stars;
-
-struct starsoptions {
- float speed;
- int maxstars;
- int depthmultiplier;
- int originx;
- int originy;
- int overscan;
-} Starfield;
-long *reflectionmap;
-BITMAP *rcolormap;
-BITMAP *ralphamap;
-
-struct charrefopt {
- char reflect;
- int replaceview;
-};
-
-struct objrefopt {
- char reflect;
- char ignorescaling;
-};
-
-struct reflectionopt {
- charrefopt *Characters;
- objrefopt *Objects;
- int blendslot;
- int blendamount;
-} Reflection;
-
-int dummy;
-
-#define LENS_WIDTH 150
-
-struct LensDistort {
- int xoffset;
- int yoffset;
-};
-
-LensDistort *lens;
-struct LensOpt {
- bool draw;
- int lenswidth;
- int lenszoom;
- int level;
- int x;
- int y;
- int clampoffset;
-} LensOption;
-
-const int alphamultiply [4096] = {
-//#include "alphamultiply.txt"
-};
-float rot_sine_LUT[360];
-float rot_cos_LUT[360];
-
-BITMAP *backgroundimage;
-
-PALSTRUCT objectivepal[256];
-int bgimgspr;
-
-void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) {
- objectivepal[index].r = r;
- objectivepal[index].b = b;
- objectivepal[index].g = g;
-}
-
-int ReadObjectivePaletteR(unsigned char index) {
- return objectivepal[index].r;
-}
-
-int ReadObjectivePaletteB(unsigned char index) {
- return objectivepal[index].b;
-}
-int ReadObjectivePaletteG(unsigned char index) {
- return objectivepal[index].g;
-}
-
-
-#define SQRT_MAGIC_F 0x5f3759df
-float q3sqrt(const float x) {
- const float xhalf = 0.5f * x;
-
- union { // get bits for floating value
- float x;
- int i;
- } u;
- u.x = x;
- u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
- return x * u.x * (1.5f - xhalf * u.x * u.x); // Newton step, repeating increases accuracy
-}
-
-void Make_Sin_Lut() {
- for (int angle = 0; angle < 360; angle++) {
- double rad = (angle * PI) / 180.0;
- rot_sine_LUT [angle] = static_cast<float>(sin(rad));
- rot_cos_LUT [angle] = static_cast<float>(cos(rad));
- }
-}
-
-/*
-void PreMultiply_Alphas () //Ha ha, this isn't the kind of premultiplcation you're thinking of.
-{
- for (int y=0;y<64;y++)
- for (int x=0;x<64;x++)
- alphamultiply [y*64+x] = y*x;
-}
-*/
-
-int GetModifiedBackgroundImage() {
- return bgimgspr;
-}
-
-unsigned short root(unsigned short x) {
- unsigned short a, b;
- b = x;
- a = x = 0x3f;
- x = b / x;
- a = x = (x + a) >> 1;
- x = b / x;
- a = x = (x + a) >> 1;
- x = b / x;
- x = (x + a) >> 1;
- return (x);
-}
-
-
-float Hill(float x) {
- const float a0 = 1.0f;
- const float a2 = 2.0f / PI - 12.0f / (pisquared);
- const float a3 = 16.0f / (picubed) - 4.0f / (pisquared);
- const float xx = x * x;
- const float xxx = xx * x;
-
- return a0 + a2 * xx + a3 * xxx;
-}
-
-float FastSin(float x) {
- // wrap x within [0, TWO_PI)
- const float a = x * twopi_inv;
- x -= static_cast<int>(a) * twopi;
- if (x < 0.0f)
- x += twopi;
-
- // 4 pieces of hills
- if (x < halfpi)
- return Hill(halfpi - x);
- else if (x < PI)
- return Hill(x - halfpi);
- else if (x < 3.0f * halfpi)
- return -Hill(3.0f * halfpi - x);
- else
- return -Hill(x - 3.0f * halfpi);
-}
-
-float FastCos(float x) {
- return FastSin(x + halfpi);
-}
-
-FLOAT_RETURN_TYPE AGSFastSin(SCRIPT_FLOAT(x)) {
- INIT_SCRIPT_FLOAT(x);
- x = FastSin(x);
- RETURN_FLOAT(x);
-}
-
-FLOAT_RETURN_TYPE AGSFastCos(SCRIPT_FLOAT(x)) {
- INIT_SCRIPT_FLOAT(x);
- x = FastSin(x + halfpi);
- RETURN_FLOAT(x);
-}
-
-
-void DrawLens(int ox, int oy) {
- int32 sh, sw = 0;
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- BITMAP *virtsc = engine->GetVirtualScreen();
- if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen.");
- BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8);
- unsigned char **vScreen = engine->GetRawBitmapSurface(virtsc);
- unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite);
- int radius = LensOption.lenswidth >> 1;
- for (int y = 0; y < LensOption.lenswidth; y++) {
- int ypos = y * LensOption.lenswidth;
- for (int x = 0; x < LensOption.lenswidth; x++) {
- int lenspos = ypos + x;
- int coffx = lens[lenspos].xoffset;
- int coffy = lens[lenspos].yoffset;
- if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) {
- lensarray[y][x] = vScreen[oy + coffy][ox + coffx];
- //vScreen[oy+coffy][ox+coffx] = ABS(coffy);
- }
- }
- }
- /*
- for (int y=0;y<LensOption.lenswidth;y++)
- {
- int ypos = y*LensOption.lenswidth;
- for (int x=0;x<LensOption.lenswidth;x++)
- {
- if (oy+y > 0 && oy+y < sh && ox+x > 0 && ox+x < sw)
- {
- vScreen[oy+y][ox+x] = lensarray[y][x];
- }
- }
- }
- */
- int radsq = radius * radius;
- for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
- int cysq = cy * cy;
- for (int cx = -radius; cx <= radius; cx++) {
- int cxsq = cx * cx;
- int dx = cx + ox;
- int dy = cy + oy;
- if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) {
- //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong");
- vScreen[dy][dx] = lensarray[cy + radius][cx + radius];
- }
- }
- }
-
- engine->ReleaseBitmapSurface(lenswrite);
- engine->ReleaseBitmapSurface(virtsc);
- engine->FreeBitmap(lenswrite);
-}
-
-void SetLensPos(int x, int y) {
- LensOption.x = x;
- LensOption.y = y;
-}
-
-int GetLensX() {
- return LensOption.x;
-}
-
-int GetLensY() {
- return LensOption.y;
-}
-
-void SetLensDrawn(int toggle) {
- if (toggle > 0) LensOption.draw = 1;
- else LensOption.draw = 0;
-}
-
-int GetLensDrawn() {
- return LensOption.draw;
-}
-
-void SetLensOffsetClamp(int clamp) {
- if (clamp < 0) LensOption.clampoffset = LensOption.lenswidth;
- else LensOption.clampoffset = clamp;
-}
-
-int GetLensOffsetClamp() {
- return LensOption.clampoffset;
-}
-
-int GetLensLevel() {
- return LensOption.level;
-}
-
-void SetLensLevel(int level) {
- if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
- else LensOption.level = level;
-}
-
-void LensInitialize(int width, int zoom, int lensx, int lensy, int level, int clamp = -1) {
- int32 sw, sh, radius;
- if (width < 1) engine->AbortGame("Invalid lens dimension!");
- radius = width >> 1;
- lens = new LensDistort [width * width]();
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- int radsq = radius * radius;
- int zoomsq = zoom * zoom;
- for (int y = 0; y < radius; y++) {
- int ysq = y * y;
- for (int x = 0; x < radius; x++) {
- int lx, ly;
- int xsq = x * x;
- if ((xsq + ysq) < (radsq)) {
- float shift = zoom / sqrt((float)(zoomsq - (xsq + ysq - radsq)));
- lx = (int)(x * shift - x);
- ly = (int)(y * shift - y);
- } else {
- lx = 0;
- ly = 0;
- }
- lens[(radius - y)*width + (radius - x)].xoffset = lx;
- lens[(radius - y)*width + (radius - x)].yoffset = ly;
- lens[(radius + y)*width + (radius + x)].xoffset = -lx;
- lens[(radius + y)*width + (radius + x)].yoffset = -ly;
- lens[(radius + y)*width + (radius - x)].xoffset = lx;
- lens[(radius + y)*width + (radius - x)].yoffset = -ly;
- lens[(radius - y)*width + (radius + x)].xoffset = -lx;
- lens[(radius - y)*width + (radius + x)].yoffset = ly;
- }
- }
- LensOption.lenswidth = width;
- LensOption.lenszoom = zoom;
- if (clamp < 0) LensOption.clampoffset = width;
- else LensOption.clampoffset = clamp;
- LensOption.x = lensx;
- LensOption.y = lensy;
- if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
- else LensOption.level = level;
-}
-
-void ResetRemapping() {
- for (int j = 0; j < 256; ++j) {
- cycle_remap [j] = j;
- }
-}
-
-#define MAX_PLASMA_COMPLEXITY 4
-int plasmatype[MAX_PLASMA_COMPLEXITY];
-int plasmadata [MAX_PLASMA_COMPLEXITY];
-int plasmadata2 [MAX_PLASMA_COMPLEXITY];
-int plasmadata3 [MAX_PLASMA_COMPLEXITY];
-int plasmaroottype;
-
-
-void SetPlasmaRootType(int real) {
- if (real) plasmaroottype = 1;
- else plasmaroottype = 0;
-}
-
-int GetPlasmaRootType() {
- return plasmaroottype;
-}
-
-void SetPlasmaType(int component, int type, int data, int data2, int data3) {
- if (component >= MAX_PLASMA_COMPLEXITY) engine->AbortGame("Plasma too complex!");
- else {
- plasmatype [component] = type;
- plasmadata [component] = data;
- plasmadata2[component] = data2;
- plasmadata3[component] = data3;
- }
-
- //0 = None.
- //1 = Horizontal Bars (data=width)
- //2 = Vertical Bars (data=width)
- //3 = Circle (data=x,data2=y,data3=width)
- //4 = Diagonal Bars (data=width)
-}
-
-void ResetPlasmaSettings() {
- int i = 0;
- while (i < MAX_PLASMA_COMPLEXITY) {
- plasmatype [i] = 0;
- plasmadata [i] = 0;
- plasmadata2[i] = 0;
- plasmadata3[i] = 0;
- i++;
- }
-}
-
-void DrawPlasma(int slot, int palstart, int palend) {
- BITMAP *plasmaspr = engine->GetSpriteGraphic(slot);
- if (!plasmaspr) engine->AbortGame("Plasma: Not a sprite I can load.");
- int32 w, h, basecol, range = 0;
- if (palend > palstart) {
- range = palend - palstart;
- basecol = palstart;
- } else {
- range = palstart - palend;
- basecol = palend;
- }
- engine->GetBitmapDimensions(plasmaspr, &w, &h, nullptr);
- unsigned char **plasmarray = engine->GetRawBitmapSurface(plasmaspr);
- double frange = range / 2.0;
- int complex = 0;
- int color = 0;
- int i = 0;
- while (i < MAX_PLASMA_COMPLEXITY) {
- if (plasmatype[i] > 0) complex++;
- i++;
- }
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- color = 0;
- for (int p = 0; p < MAX_PLASMA_COMPLEXITY; p++) {
- if (plasmatype[p] == 1) { //1 = Horizontal Bars (data=width)
- color += int(frange + (frange * FastSin(y / (float)plasmadata[p])));
- } else if (plasmatype[p] == 2) { //2 = Vertical Bars (data=width)
- color += int(frange + (frange * FastSin(x / (float)plasmadata[p])));
- } else if (plasmatype[p] == 3) { //3 = Circle (data=x,data2=y,data3=width)
- int cx, cy = 0;
- cx = plasmadata [p];
- cy = plasmadata2 [p];
- if (plasmaroottype == 1) color += int(frange + (frange * FastSin(q3sqrt((float)((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
- else color += int(frange + (frange * FastSin(root(((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
- } else if (plasmatype[p] == 4) { //4 = Diagonal Bars (data=width)
- color += int(frange + (frange * FastSin((x + y) / (float)plasmadata[p])));
- }
- }
- if (color > 0 && complex > 0) color = color / complex;
- plasmarray[y][x] = static_cast<unsigned char>(basecol + color);
- }
- }
- engine->ReleaseBitmapSurface(plasmaspr);
- engine->NotifySpriteUpdated(slot);
-}
-
-void DoFire(int spriteId, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) {
- BITMAP *firespr = engine->GetSpriteGraphic(masksprite);
- BITMAP *firecolorspr = engine->GetSpriteGraphic(spriteId);
- BITMAP *seedspr;
- int32 w, h = 0;
- int range, basecol, dir = 0;
- if (palend > palstart) {
- range = palend - palstart;
- basecol = palstart;
- dir = 1;
- } else {
- range = palstart - palend;
- basecol = palend;
- dir = -1;
- }
- int divider = 256 / range;
- engine->GetBitmapDimensions(firespr, &w, &h, nullptr);
- unsigned char **fire = engine->GetRawBitmapSurface(firespr);
- unsigned char **color = engine->GetRawBitmapSurface(firecolorspr);
- int sparky = 0;
- //srand(time(NULL));
- for (int y = 0; y < h - 1; y++) {
- if ((int)::AGS::g_vm->getRandomNumber(9) > 7 - windspeed) { //Wind right
- for (int x = w - 1; x > 1; x--) {
- fire[y][x] = fire[y][x - 1];
- }
- } else if ((int)::AGS::g_vm->getRandomNumber(9) > 7 + windspeed) { // wind left
- for (int x = 0; x < w - 1; x++) {
- fire[y][x] = fire[y][x + 1];
- }
- }
- }
- for (int x = 0; x < w; x++) {
- sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
- if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
- ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
- fire[h - sparky][x] = 255;
- sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
- if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
- ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
- fire[h - sparky][x] = 0;
- }
- if (seed == 0) {
- for (int x = 0; x < w; x++)
- fire[h - 1][x] = 255;
- for (int x = 0; x < w; x++)
- fire[h - 2][x] = ::AGS::g_vm->getRandomNumber(255);
- } else if (seed > 0) {
- seedspr = engine->GetSpriteGraphic(seed);
- BITMAP *virtsc = engine->GetVirtualScreen();
- engine->SetVirtualScreen(firespr);
- engine->BlitBitmap(0, 0, seedspr, 1);
- engine->SetVirtualScreen(virtsc);
- engine->ReleaseBitmapSurface(virtsc);
- engine->ReleaseBitmapSurface(seedspr);
- engine->NotifySpriteUpdated(spriteId);
- engine->NotifySpriteUpdated(masksprite);
- }
-
- for (int y = 0; y < h - 1; y++) {
- for (int x = 0; x < w; x++) {
- fire[y][x] =
- ((fire[(y + 1) % h][(x - 1 + w) % w]
- + fire[(y + 1) % h][(x) % w]
- + fire[(y + 1) % h][(x + 1) % w]
- + fire[(y + 2) % h][(x) % w])
- * 100) / (400 + (100 - strength));
- if (fire[y][x] < cutoff) fire[y][x] = 0;
- //if (fire[y][x] ==255) color [y][x] = palend;
- else color [y][x] = static_cast<unsigned char>(basecol + (fire[y][x] / divider) * dir);
- }
- }
- engine->ReleaseBitmapSurface(firespr);
- engine->ReleaseBitmapSurface(firecolorspr);
- engine->NotifySpriteUpdated(spriteId);
- engine->NotifySpriteUpdated(masksprite);
-}
-
-/*
-unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha)
-{
- //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette ();
- int i=0;
- int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
- int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
- int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
- //unsigned char ralpha = alpha>>2;
- //unsigned char invralpha = 64-ralpha;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //int out_r = alphamultiply[(palette[fg].r>>1)][ralpha] + alphamultiply[(palette[bg].r>>1)][(invralpha)];
- //int out_g = alphamultiply[(palette[fg].g)][ralpha] + alphamultiply[(palette[bg].g)][(invralpha)];
- //int out_b = alphamultiply[(palette[fg].b>>1)][ralpha] + alphamultiply[(palette[bg].b>>1)][(invralpha)];
- out_r = (out_r + 1 + (out_r >> 8)) >> 8;
- out_g = (out_g + 1 + (out_g >> 8)) >> 8;
- out_b = (out_b + 1 + (out_b >> 8)) >> 8;
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-
-unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha)
-{
- //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette ();
- int i=0;
- int add_r,add_b,add_g = 0;
- char ralpha = alpha>>2;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //add_r = (((palette[fg].r>>1) * (alpha))>>8);
- //add_b = (((palette[fg].b>>1) * (alpha))>>8);
- //add_g = (((palette[fg].g) * (alpha))>>8);
- add_r = ((alphamultiply[(palette[fg].r>>1)*64+ralpha])>>6);
- add_b = ((alphamultiply[(palette[fg].b>>1)*64+ralpha])>>6);
- add_g = ((alphamultiply[(palette[fg].g )*64+ralpha])>>6);
- int out_r = min(31,(palette[bg].r>>1) + add_r);
- int out_g = min(63, palette[bg].g + add_g);
- int out_b = min(31,(palette[bg].b>>1) + add_b);
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-*/
-unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b) {
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- int i = ((r << 11) | (g << 5) | b);
- unsigned char (*clutp) = clut;
- unsigned char result = *(clutp + i);
- result = cycle_remap [result]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-
-void CycleRemap(int start, int end) {
- if (end > start) {
- // Rotate left
- int wraparound = cycle_remap [start];
- for (; start < end; ++start) {
- cycle_remap [start] = cycle_remap [start + 1];
- }
- cycle_remap [end] = wraparound;
- } else if (end < start) {
- // Rotate right
- int wraparound = cycle_remap [start];
- for (; start > end; --start) {
- cycle_remap [start] = cycle_remap [start - 1];
- }
- cycle_remap [end] = wraparound;
-
- }
-}
-
-unsigned char GetRemappedSlot(unsigned char slot) {
- return cycle_remap [slot];
-}
-
-int LoadCLUT(int slot) {
- if (engine->GetSpriteWidth(slot) != 256 || engine->GetSpriteHeight(slot) != 256) return 1;
- BITMAP *clutimage = engine->GetSpriteGraphic(slot);
- unsigned char **clutarray = engine->GetRawBitmapSurface(clutimage);
- for (int y = 0; y < 256; y++) {
- for (int x = 0; x < 256; x++) {
- clut[y * 256 + x] = clutarray[y][x];
- }
- }
- clutslot = slot;
- engine->ReleaseBitmapSurface(clutimage);
- return 0;
-}
-
-void SetReflections(int toggle) {
- drawreflections = toggle;
-}
-
-int IsReflectionsOn() {
- return drawreflections;
-}
-
-int GetLuminosityFromPalette(int slot) {
- AGSColor *pal = engine->GetPalette();
- int lum = (pal[slot].r +
- pal[slot].r +
- pal[slot].r +
- pal[slot].g +
- pal[slot].g +
- pal[slot].g +
- pal[slot].g +
- pal[slot].b) >> 3;
- return lum;
-}
-
-
-
-void SetStarsOriginPoint(int x, int y) {
- Starfield.originx = x;
- Starfield.originy = y;
-}
-void InitializeStars(int slot, int maxstars) {
- int32 sw, sh = 0;
- BITMAP *canvas = engine->GetSpriteGraphic(slot);
- engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
- Starfield.maxstars = maxstars;
- Starfield.overscan = 20;
- stars = new starstype [Starfield.maxstars];
- for (int i = 0; i < Starfield.maxstars; i++) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh;
- stars[i].z = (float)(MAX_DEPTH);
- stars[i].color = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 240);
- stars[i].sprite = 0;
- stars[i].maxrad = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 5);
- }
-}
-
-void IterateStars(int slot) {
- long sw, sh = 0;
- sw = engine->GetSpriteWidth(slot);
- sh = engine->GetSpriteHeight(slot);
- for (int i = 0; i < Starfield.maxstars; i++) {
- stars[i].z -= Starfield.speed;
- //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
- float k = Starfield.depthmultiplier / stars[i].z;
- int px = static_cast<int>(stars[i].x * k + Starfield.originx);
- int py = static_cast<int>(stars[i].y * k + Starfield.originy);
- if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
- stars[i].z = (float)MAX_DEPTH;
- //stars[i].color = (rand () %240);
- }
- }
-}
-int GetStarfieldOverscan() {
- return Starfield.overscan;
-}
-void SetStarfieldOverscan(int overscan) {
- Starfield.overscan = overscan;
-}
-
-int GetStarfieldOriginX() {
- return Starfield.originx;
-}
-
-int GetStarfieldOriginY() {
- return Starfield.originy;
-}
-
-void SetStarfieldDepthMultiplier(int multi) {
- Starfield.depthmultiplier = multi;
-}
-
-int GetStarfieldDepthMultiplier() {
- return Starfield.depthmultiplier;
-}
-
-int GetStarfieldMaxStars() {
- return Starfield.maxstars;
-}
-
-void SetStarSpriteScaleBoost(int star, int boost) {
- stars[star].scaleboost = boost;
-}
-
-int GetStarSpriteScaleBoost(int star) {
- return stars[star].scaleboost;
-}
-
-void SetStarMaxRadius(int star, int radius) {
- stars[star].maxrad = radius;
-}
-
-int GetStarMaxRadius(int star) {
- return stars[star].maxrad;
-}
-
-void RotateStar(int star, int angle, int px, int py) {
- float rsin = rot_sine_LUT[angle];
- float rcos = rot_cos_LUT[angle];
- float fPx = (float)px;
- float fPy = (float)py;
- float x1 = 0, y1 = 0, xRot = 0, yRot = 0;
- int i = star;
- x1 = stars[i].x;
- y1 = stars[i].y;
- xRot = fPx + rcos * (x1 - fPx) - rsin * (y1 - fPy);
- yRot = fPy + rsin * (x1 - fPx) + rcos * (y1 - fPy);
- stars[i].x = xRot;
- stars[i].y = yRot;
- i++;
-}
-
-FLOAT_RETURN_TYPE GetStarX(int i) {
- float starx = (float)stars[i].x;
- RETURN_FLOAT(starx);
-}
-
-FLOAT_RETURN_TYPE GetStarY(int i) {
- float stary = (float)stars[i].y;
- RETURN_FLOAT(stary);
-}
-
-FLOAT_RETURN_TYPE GetStarZ(int i) {
- float starz = (float)stars[i].z;
- RETURN_FLOAT(starz);
-}
-
-void SetStarPosition(int star, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), SCRIPT_FLOAT(z)) {
- INIT_SCRIPT_FLOAT(x);
- INIT_SCRIPT_FLOAT(y);
- INIT_SCRIPT_FLOAT(z);
- stars[star].x = x;
- stars[star].y = y;
- stars[star].z = z;
-}
-
-void SetStarColor(int star, unsigned char color) {
- stars[star].color = color;
-}
-
-unsigned char GetStarColor(int star) {
- return stars[star].color;
-}
-
-void SetStarSprite(int star, int slot) {
- stars[star].sprite = slot;
-}
-
-int GetStarSprite(int star) {
- return stars[star].sprite;
-}
-
-void SetStarSpriteRange(int start, int end, int slot) {
- int sfix = start;
- int efix = end;
- if (start > Starfield.maxstars) sfix = Starfield.maxstars - 1;
- if (end > Starfield.maxstars) efix = Starfield.maxstars;
- for (int i = sfix; i < efix; i++)
- stars[i].sprite = slot;
-}
-
-void DrawStars(int slot, int maskslot) {
- int32 sw, sh = 0;
- BITMAP *canvas = engine->GetSpriteGraphic(slot);
- if (!canvas) engine->AbortGame("DrawStars: Can't load sprite slot.");
- BITMAP *maskcanvas = engine->GetSpriteGraphic(maskslot);
- if (!maskcanvas) engine->AbortGame("DrawStars: Can't load mask slot.");
- engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
- unsigned char **screenarray = engine->GetRawBitmapSurface(canvas);
- unsigned char **maskarray = engine->GetRawBitmapSurface(maskcanvas);
- for (int i = 0; i < Starfield.maxstars; i++) {
- //stars[i].z-= 0.5;
- //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
- float k = (float)Starfield.depthmultiplier / stars[i].z;
- int px = static_cast<int>(stars[i].x * k + Starfield.originx);
- int py = static_cast<int>(stars[i].y * k + Starfield.originy);
- if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
- stars[i].z = (float)MAX_DEPTH;
- //stars[i].color = (rand () %240);
- } else if (stars[i].z > 0) {
- int ivalue = (63 - (int)stars[i].z);
- if (ivalue > 63) ivalue = 63;
- else if (ivalue < 0) ivalue = 0;
- unsigned char value = (unsigned char)(ivalue);
- unsigned char maskcolor = value << 2;
- if (stars[i].sprite > 0) {
- BITMAP *origspr = engine->GetSpriteGraphic(stars[i].sprite);
- int scale = (ivalue + 1) * 100 >> 6;
- //int scale = 50;
- if (scale < 1) scale = 1;
- /*
- if (scale != 100)
- {
- unsigned char** orig = engine->GetRawBitmapSurface (origspr);
- int32 h1,h2,w1,w2=0;
- double fw2,fh2;
- engine->GetBitmapDimensions (origspr,&w1,&h1,NULL);
- fh2 = h1 * (scale / 100.0);
- fw2 = w1 * (scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- if (w2 < 1) w2 = 1;
- if (h2 < 1) h2 = 1;
- resizspr = engine->CreateBlankBitmap (w2,h2,8);
- unsigned char** resized = engine->GetRawBitmapSurface (resizspr);
- int x_ratio = (int)((w1<<16)/w2) +1;
- int y_ratio = (int)((h1<<16)/h2) +1;
- int x2, y2 ;
- for (int i=0;i<h2;i++)
- {
- for (int j=0;j<w2;j++)
- {
- x2 = ((j*x_ratio)>>16) ;
- y2 = ((i*y_ratio)>>16) ;
- resized [i][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface (resizspr);
- }
- //resizspr = origspr;
- int32 w,h=0;
- engine->GetBitmapDimensions (resizspr,&w,&h,NULL);
- unsigned char **imagemap = engine->GetRawBitmapSurface (resizspr);
- int ox = px - (w>>1);
- int oy = py - (h>>1);
- for (int dy=0;dy<h;dy++)
- {
- for (int dx=0;dx<w;dx++)
- {
- int ex = ox+dx;
- int ey = oy+dy;
- if (ex < sw && ex >= 0 && ey < sh && ey >= 0)
- {
- if (maskcolor > maskarray [ey][ex] && imagemap[dy][dx] > 0)
- {
- maskarray [ey][ex] = maskcolor;
- screenarray [ey][ex] = imagemap[dy][dx];
- }
- }
- }
- }
- */
-
- unsigned char **orig = engine->GetRawBitmapSurface(origspr);
- int32 h1, h2, w1, w2 = 0;
- double fw2, fh2;
- engine->GetBitmapDimensions(origspr, &w1, &h1, nullptr);
- fh2 = h1 * (scale / 100.0);
- fw2 = w1 * (scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- if (w2 < 1) w2 = 1;
- if (h2 < 1) h2 = 1;
- int x_ratio = (int)((w1 << 16) / w2) + 1;
- int y_ratio = (int)((h1 << 16) / h2) + 1;
- int x2, y2 ;
- int ox = px - (w2 >> 1);
- int oy = py - (h2 >> 1);
- for (int ii = 0; ii < h2; ii++) {
- int temprzy = ii * y_ratio;
- int ey = oy + ii;
- for (int j = 0; j < w2; j++) {
- x2 = ((j * x_ratio) >> 16);
- y2 = ((temprzy) >> 16);
- int ex = ox + j;
- if (ex < sw && ex >= 0 && ey < sh && ey >= 0) {
- if (maskcolor > maskarray [ey][ex] && orig[y2][x2] > 0) {
- maskarray [ey][ex] = maskcolor;
- screenarray [ey][ex] = orig[y2][x2];
- }
- }
- //resized [ii][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface(origspr);
- } else if (stars[i].sprite == 0) {
- if (stars[i].maxrad == 1) {
- if (px < sw && px >= 0 && py < sh && py >= 0) {
- if (maskcolor > maskarray[py][px]) {
- maskarray[py][px] = maskcolor;
- screenarray[py][px] = stars[i].color;
- }
- }
- } else {
- int scale = ((((int)stars[i].z) * 100) / 63);
- if (scale < 1) scale = 1;
- int radius = (stars[i].maxrad * (100 - scale) / 100);
- int radsq = radius * radius;
- //unsigned char color = GetColor565 (value>>1,value,value>>1);
- unsigned char color = stars[i].color;
- for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
- int cysq = cy * cy;
- for (int cx = -radius; cx <= radius; cx++) {
- int cxsq = cx * cx;
- int dx = cx + px;
- int dy = cy + py;
- if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) {
- if (maskcolor > maskarray [dy][dx]) {
- maskarray [dy][dx] = maskcolor;
- screenarray [dy][dx] = color;
- }
- }
- }
- }
- /*
- for(int cy=-radius; cy<=radius; cy++) //Draw a circle around the point, for the color.
- {
- int cysq = cy*cy;
- for(int cx=-radius; cx<=radius; cx++)
- {
- int cxsq = cx*cx;
- int dx = cx+px;
- int dy = cy+py;
- if((cxsq+cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0)
- {
- if (maskarray [dy][dx] == maskcolor)screenarray [dy][dx] = color;
- }
- }
- }
- */
- }
- }
- }
- }
- engine->ReleaseBitmapSurface(canvas);
- engine->ReleaseBitmapSurface(maskcanvas);
- engine->NotifySpriteUpdated(slot);
- engine->NotifySpriteUpdated(maskslot);
-}
-
-
-int CreateTranslucentOverlay(int id, int spriteId, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) {
- BITMAP *testspr = engine->GetSpriteGraphic(spriteId);
- if (testspr) overlay[id].sprite = spriteId;
- else engine->AbortGame("CreateTranslucentOverlay: Invalid spriteId.");
- engine->ReleaseBitmapSurface(testspr);
- overlay[id].level = MAX(0, MIN(level, 4));
- overlay[id].trans = MAX(0, MIN(alpha, 255));
- overlay[id].spritemask = mask;
- overlay[id].x = ox;
- overlay[id].y = oy;
- overlay[id].enabled = true;
- overlay[id].blendtype = blendmode;
- return 0;
-}
-
-int DeleteTranslucentOverlay(int id) {
- overlay[id].enabled = false;
- overlay[id].sprite = 0;
- overlay[id].x = 0;
- overlay[id].y = 0;
- overlay[id].level = 0;
- overlay[id].trans = 0;
- return 0;
-}
-
-int MoveTranslucentOverlay(int id, int ox, int oy) {
- overlay[id].x = ox;
- overlay[id].y = oy;
- return 0;
-}
-
-int GetTranslucentOverlayX(int id) {
- return overlay[id].x;
-}
-
-int GetTranslucentOverlayY(int id) {
- return overlay[id].y;
-}
-
-int GetTranslucentOverlaySprite(int id) {
- return overlay[id].sprite;
-}
-
-int GetTranslucentOverlayLevel(int id) {
- return overlay[id].level;
-}
-
-int GetTranslucentOverlayEnabled(int id) {
- return overlay[id].enabled;
-}
-
-int GetTranslucentOverlayAlpha(int id) {
- return overlay[id].trans;
-}
-
-int SetTranslucentOverlayAlpha(int id, int alpha) {
- if (alpha >= 0 && alpha < 256)
- overlay[id].trans = alpha;
- else
- engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected.");
- return 0;
-}
-
-int SetTranslucentOverlayEnabled(int id, int toggle) {
- if (toggle > 0)
- overlay[id].enabled = true;
- else
- overlay[id].enabled = false;
- return 0;
-}
-
-void SetCharacterReflected(int id, int refl) {
- if (refl > 0) Reflection.Characters[id].reflect = 1;
- else Reflection.Characters[id].reflect = 0;
-}
-
-void SetObjectReflected(int id, int refl) {
- if (refl > 0)
- Reflection.Objects[id].reflect = 1;
- else
- Reflection.Objects[id].reflect = 0;
-}
-
-int GetCharacterReflected(int id) {
- return Reflection.Characters[id].reflect;
-}
-
-int GetObjectReflected(int id) {
- return Reflection.Objects[id].reflect;
-}
-
-void ReplaceCharacterReflectionView(int id, int view) {
- Reflection.Characters[id].replaceview = view - 1;
-}
-
-void SetObjectReflectionIgnoreScaling(int id, int wb) {
- if (wb) Reflection.Objects[id].ignorescaling = 1;
- else Reflection.Objects[id].ignorescaling = 0;
-}
-
-int DrawReflections(int id, int charobj = 0) {
- int32 screenw, screenh;
- int32 bgw, bgh;
- engine->GetScreenDimensions(&screenw, &screenh, nullptr);
- BITMAP *bgmask = engine->GetBackgroundScene(1);
- if (bgmask == nullptr) return 1;
- //BITMAP *virtsc = engine->GetVirtualScreen();
- BITMAP *walkbehind = engine->GetRoomMask(MASK_WALKBEHIND);
- //if (!virtsc) engine->AbortGame ("Can't load virtual screen.");
- if (!walkbehind) engine->AbortGame("DrawRelfections: Can't load Walkbehind into memory.");
- engine->GetBitmapDimensions(walkbehind, &bgw, &bgh, nullptr);
- if (!bgmask) engine->AbortGame("DrawReflections: Can't load reflection mask.");
- //unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc);
- unsigned char **wbarray = engine->GetRawBitmapSurface(walkbehind);
- unsigned char **maskarray = engine->GetRawBitmapSurface(bgmask);
- //Initialize stuff
- BITMAP *charsprite = nullptr;
- BITMAP *charsprite2 = nullptr;
- AGSCharacter *currchar = nullptr;
- AGSObject *currobj;
- int cox = 0, coy = 0, coz = 0;
- int scale = 0;
- //Get character, and their sprite.
- if (charobj == 0) {
- currchar = engine->GetCharacter(id);
- /*int view = 0;
- if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1;
- else view = Reflection.Characters[id].replaceview;
- */
- AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame);
- charsprite = engine->GetSpriteGraphic(vf->pic);
- long scaling = currchar->flags & CHF_NOSCALING;
- if (!scaling)scale = engine->GetAreaScaling(currchar->x, currchar->y);
- else scale = 100;
- cox = currchar->x;
- coy = currchar->y;
- coz = currchar->z;
- } else if (charobj == 1) {
- currobj = engine->GetObject(id);
-
- charsprite = engine->GetSpriteGraphic(currobj->num);
- if (Reflection.Objects[id].ignorescaling) scale = 100;
- else scale = engine->GetAreaScaling(currobj->x, currobj->y);
- cox = currobj->x;
- if (currobj->baseline < 0) coy = currobj->y;
- else coy = currobj->baseline;
- coz = 0;
- }
- bool scaled = false;
- int32 w, h;
- engine->GetBitmapDimensions(charsprite, &w, &h, nullptr);
- if (scale != 100) {
- unsigned char **orig = engine->GetRawBitmapSurface(charsprite);
- int h1, h2, w1, w2;
- double fw2, fh2;
- h1 = h;
- w1 = w;
- fh2 = h1 * ((double)scale / 100.0);
- fw2 = w1 * ((double)scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- charsprite2 = engine->CreateBlankBitmap(w2, h2, 8);
- unsigned char **resized = engine->GetRawBitmapSurface(charsprite2);
- int x_ratio = (int)((w1 << 16) / w2) + 1;
- int y_ratio = (int)((h1 << 16) / h2) + 1;
- int x2, y2 ;
- for (int i = 0; i < h2; i++) {
- for (int j = 0; j < w2; j++) {
- x2 = ((j * x_ratio) >> 16) ;
- y2 = ((i * y_ratio) >> 16) ;
- resized [i][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface(charsprite2);
- scaled = true;
- w = w2;
- h = h2;
- } else {
- charsprite2 = charsprite;
- }
- int transamount = 0;
- unsigned char **spritearray = engine->GetRawBitmapSurface(charsprite2);
- unsigned char **charbuffer = engine->GetRawBitmapSurface(rcolormap);
- unsigned char **alphaarray = engine->GetRawBitmapSurface(ralphamap);
- int i = h - 1, j = 0;
- int32 ox = cox;
- if (charobj == 0) ox = ox - (w / 2);
- int32 oy = coy + coz - 1;
- engine->RoomToViewport(&ox, &oy);
- int yoffset = 0;
- int translevel = 7;
- //bool dither = false;
- //bool dodither = false;
- int counter = 0;
- int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0));
- int delay = screenh / rowcount;
- int *obst;
- int flipped = 0;
- if (charobj == 0) {
- int (*sfGetGameParameter)(int, int, int, int);
- sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
- flipped = sfGetGameParameter(13, currchar->view + 1, currchar->loop, currchar->frame);
- } else flipped = 0;
- obst = new int [w];
- for (int k = 0; k < w; k++) {
- obst[k] = 0;
- }
- while (i > 0) {
- //if ((counter == delay/2-1 || counter == delay-1) && yoffset < 36) dodither = (!dodither);
- if (counter == delay) {
- counter = 0;
- if (translevel > 0) translevel--;
- } else counter++;
- yoffset++;
- while (j < w) {
- int xoffset;
- if (flipped == 1) xoffset = w - j - 1;
- else xoffset = j;
- int32 rx = ox + xoffset, ry = oy + yoffset;
- int wbb = 0;
- engine->ViewportToRoom(&rx, &ry);
- if (ry > 0 && ry < bgh && rx > 0 && rx < bgw) {
- if (wbarray [ry][rx] > 0) {
- wbb = engine->GetWalkbehindBaseline(wbarray[ry][rx]);
- }
- if (maskarray[ry][rx] == 21) obst[j] = 1;
- }
-
- //dither = (!dither);
- transamount = 32 * translevel;
- if (spritearray [i][j] != 0 && oy + yoffset < screenh && ox + xoffset < screenw && oy + yoffset >= 0 && ox + xoffset >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg.
- if (wbb < ry && obst[j] == 0 && (oy > reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))])) {
- //charbuffer[oy+yoffset][ox+xoffset] = MixColorAlpha (spritearray [i][j],charbuffer[oy+yoffset][ox+xoffset],transamount);
- charbuffer [oy + yoffset][ox + xoffset] = spritearray [i][j];
- alphaarray [oy + yoffset][ox + xoffset] = transamount;
- reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))] = oy;
- }
- }
- j++;
- }
- //if (w % 2 == 0) dither = (!dither);
- i--;
- j = 0;
- }
-
- delete [] obst;
- if (scaled == true)engine->FreeBitmap(charsprite2);
- engine->ReleaseBitmapSurface(charsprite);
- //engine->ReleaseBitmapSurface (virtsc);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(bgmask);
- engine->ReleaseBitmapSurface(walkbehind);
- engine->ReleaseBitmapSurface(rcolormap);
- engine->ReleaseBitmapSurface(ralphamap);
- engine->MarkRegionDirty(ox, oy, ox + w, oy + h);
- return 0;
-}
-
-
-int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) {
- BITMAP *maskspr = nullptr;
- unsigned char **maskarray = nullptr;
- if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
- if (!maskspr && mask > 0) {
- char maskerr [100];
- snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
- engine->AbortGame(maskerr);
- }
- // Get a reference to the screen we'll draw onto
- BITMAP *bgspr = engine->GetSpriteGraphic(bg);
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
- if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background");
- //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
- if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay spriteId into memory.");
- // Get its surface
- int32 sprw, sprh, coldepth;
- int32 bgw, bgh;
- engine->GetBitmapDimensions(bgspr, &bgw, &bgh, &coldepth);
- engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
-
- unsigned char **bgarray = engine->GetRawBitmapSurface(bgspr);
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
- if (mask > 0) maskarray = engine->GetRawBitmapSurface(maskspr);
- int tloffset = 255 - translevel;
- int x = 0;
- int y = 0;
- //int transamount = 256 * translevel; //old
- while (y < sprh) {
- while (x < sprw) {
- if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the bg.
- if (mask > 0) {
- translevel = MAX(maskarray [y][x] - tloffset, 0);
- }
- //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
- if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
- else if (blendmode == 1) spritearray[y][x] = Mix::MixColorAdditive(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
- }
- x++;
- }
- x = 0;
- y++;
- }
-
- // Release the screen so that the engine can continue
- engine->ReleaseBitmapSurface(bgspr);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(spritespr);
- engine->NotifySpriteUpdated(spriteId);
- return 0;
-}
-
-int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) {
- if (translevel == 0) return 0;
- BITMAP *maskspr = nullptr;
- unsigned char **maskarray = nullptr;
- // Get a reference to the screen we'll draw onto
- BITMAP *virtsc = engine->GetVirtualScreen();
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
- if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
- if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen.");
- //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
- if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay spriteId into memory.");
- // Get its surface
- int32 sprw, sprh, coldepth;
- int32 screenw, screenh;
- engine->GetScreenDimensions(&screenw, &screenh, &coldepth);
- engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
- unsigned char **charbuffer = engine->GetRawBitmapSurface(virtsc);
- unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
- if (mask > 0) {
- if (!maskspr && mask > 0) {
- char maskerr [100];
- snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
- engine->AbortGame(maskerr);
- }
- maskarray = engine->GetRawBitmapSurface(maskspr);
- }
- int tloffset = 255 - translevel;
- int x = 0;
- int y = 0;
- //int transamount = 256 * translevel; //old
- while (y < sprh) {
- while (x < sprw) {
- if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the screen.
- //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
- if (mask > 0) {
- translevel = MAX(maskarray [y][x] - tloffset, 0);
- }
- if (blendmode == 0) {
- if (translevel == 255) {
- charbuffer[y + oy][x + ox] = spritearray [y][x];
- } else charbuffer[y + oy][x + ox] = Mix::MixColorAlpha(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
- } else if (blendmode == 1) charbuffer[y + oy][x + ox] = Mix::MixColorAdditive(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
- }
- x++;
- }
- x = 0;
- y++;
- }
-
- // Release the screen so that the engine can continue
- long dirtywidth = ox + sprw;
- if (dirtywidth > screenw) dirtywidth = screenw - 1;
- long dirtyheight = oy + sprh;
- if (dirtyheight > screenh) dirtywidth = screenh - 1;
- engine->ReleaseBitmapSurface(virtsc);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(spritespr);
- if (mask > 0) engine->ReleaseBitmapSurface(maskspr);
- engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight);
-
- return 0;
-}
-
-/*------------------------------------------------------------------*/
-
-AGSPalRender::AGSPalRender() : DLL() {
- DLL_METHOD(AGS_GetPluginName);
- DLL_METHOD(AGS_EngineStartup);
- DLL_METHOD(AGS_EngineShutdown);
- DLL_METHOD(AGS_EngineOnEvent);
-}
-
-const char *AGSPalRender::AGS_GetPluginName() {
- return "PALgorithms Translucent Overlay Renderer";
-}
-
-void AGSPalRender::AGS_EngineStartup(IAGSEngine *lpEngine) {
- engine = lpEngine;
-
- // Make sure it's got the version with the features we need
- if (engine->version < 3) {
- engine->AbortGame("Engine interface is too old, need newer version of AGS.");
- }
- engine->RegisterScriptFunction("PALInternal::LoadCLUT^1", (void *)LoadCLUT);
- engine->RegisterScriptFunction("PALInternal::CycleRemap^2", (void *)CycleRemap);
- engine->RegisterScriptFunction("PALInternal::GetColor565^3", (void *)GetColor565);
- engine->RegisterScriptFunction("PALInternal::GetLuminosityFromPalette^1", (void *)GetLuminosityFromPalette);
- engine->RegisterScriptFunction("PALInternal::FastSin^1", (void *)AGSFastSin);
- engine->RegisterScriptFunction("PALInternal::FastCos^1", (void *)AGSFastCos);
- engine->RegisterScriptFunction("PALInternal::FastRoot^1", (void *)root);
- engine->RegisterScriptFunction("PALInternal::GetRemappedSlot^1", (void *)GetRemappedSlot);
- engine->RegisterScriptFunction("PALInternal::ResetRemapping^0", (void *)ResetRemapping);
- engine->RegisterScriptFunction("PALInternal::GetModifiedBackgroundImage", (void *)GetModifiedBackgroundImage);
- engine->RegisterScriptFunction("PALInternal::WriteObjectivePalette^4", (void *)WriteObjectivePalette);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteR^1", (void *)ReadObjectivePaletteR);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteB^1", (void *)ReadObjectivePaletteB);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteG^1", (void *)ReadObjectivePaletteG);
-
- engine->RegisterScriptFunction("Raycast::Render^1", (void *)Raycast_Render);
- engine->RegisterScriptFunction("Raycast::LoadMap^4", (void *)LoadMap);
- engine->RegisterScriptFunction("Raycast::Initialize", (void *)Init_Raycaster);
- engine->RegisterScriptFunction("Raycast::MakeTextures^1", (void *)MakeTextures);
- engine->RegisterScriptFunction("Raycast::MoveForward^0", (void *)MoveForward);
- engine->RegisterScriptFunction("Raycast::MoveBackward^0", (void *)MoveBackward);
- engine->RegisterScriptFunction("Raycast::RotateLeft^0", (void *)RotateLeft);
- engine->RegisterScriptFunction("Raycast::RotateRight^0", (void *)RotateRight);
- engine->RegisterScriptFunction("Raycast::SetCameraPosition^2", (void *)Ray_SetPlayerPosition);
- engine->RegisterScriptFunction("Raycast::GetCameraX^0", (void *)Ray_GetPlayerX);
- engine->RegisterScriptFunction("Raycast::GetCameraY^0", (void *)Ray_GetPlayerY);
- engine->RegisterScriptFunction("Raycast::GetCameraAngle^0", (void *)Ray_GetPlayerAngle);
- engine->RegisterScriptFunction("Raycast::SetCameraAngle^1", (void *)Ray_SetPlayerAngle);
- engine->RegisterScriptFunction("Raycast::InitSprite^9", (void *)Ray_InitSprite);
- engine->RegisterScriptFunction("Raycast::UnloadEngine^0", (void *)QuitCleanup);
- engine->RegisterScriptFunction("Raycast::GetHotspotAtXY^2", (void *)Ray_GetHotspotAt);
- engine->RegisterScriptFunction("Raycast::GetObjectAtXY^2", (void *)Ray_GetObjectAt);
- engine->RegisterScriptFunction("Raycast::SetSpriteInteractObj^2", (void *)Ray_SetSpriteInteractObj);
- engine->RegisterScriptFunction("Raycast::GetSpriteInteractObj^1", (void *)Ray_GetSpriteInteractObj);
- engine->RegisterScriptFunction("Raycast::SetSpritePosition^3", (void *)Ray_SetSpritePosition);
- engine->RegisterScriptFunction("Raycast::SetSpriteVertOffset^2", (void *)Ray_SetSpriteVertOffset);
- engine->RegisterScriptFunction("Raycast::GetSpriteVertOffset^1", (void *)Ray_GetSpriteVertOffset);
- engine->RegisterScriptFunction("Raycast::GetSpriteX^1", (void *)Ray_GetSpriteX);
- engine->RegisterScriptFunction("Raycast::GetSpriteY^1", (void *)Ray_GetSpriteY);
- engine->RegisterScriptFunction("Raycast::SetWallHotspot^2", (void *)Ray_SetWallHotspot);
- engine->RegisterScriptFunction("Raycast::SetWallTextures^5", (void *)Ray_SetWallTextures);
- engine->RegisterScriptFunction("Raycast::SetWallSolid^5", (void *)Ray_SetWallSolid);
- engine->RegisterScriptFunction("Raycast::SetWallIgnoreLighting^5", (void *)Ray_SetWallIgnoreLighting);
- engine->RegisterScriptFunction("Raycast::SetWallAlpha^5", (void *)Ray_SetWallAlpha);
- engine->RegisterScriptFunction("Raycast::SetWallBlendType^5", (void *)Ray_SetWallBlendType);
- engine->RegisterScriptFunction("Raycast::GetMoveSpeed^0", (void *)Ray_GetMoveSpeed);
- engine->RegisterScriptFunction("Raycast::SetMoveSpeed^1", (void *)Ray_SetMoveSpeed);
- engine->RegisterScriptFunction("Raycast::GetRotSpeed^0", (void *)Ray_GetRotSpeed);
- engine->RegisterScriptFunction("Raycast::SetRotSpeed^1", (void *)Ray_SetRotSpeed);
- engine->RegisterScriptFunction("Raycast::GetWallAt^2", (void *)Ray_GetWallAt);
- engine->RegisterScriptFunction("Raycast::GetLightAt^2", (void *)Ray_GetLightAt);
- engine->RegisterScriptFunction("Raycast::SetLightAt^3", (void *)Ray_SetLightAt);
- engine->RegisterScriptFunction("Raycast::SetWallAt^3", (void *)Ray_SetWallAt);
- engine->RegisterScriptFunction("Raycast::SetPlaneY^1", (void *)Ray_SetPlaneY);
- engine->RegisterScriptFunction("Raycast::GetDistanceAt^2", (void *)Ray_GetDistanceAt);
- engine->RegisterScriptFunction("Raycast::GetSpriteAngle^1", (void *)Ray_GetSpriteAngle);
- engine->RegisterScriptFunction("Raycast::SetSpriteAngle^2", (void *)Ray_SetSpriteAngle);
- engine->RegisterScriptFunction("Raycast::SetSpriteView^2", (void *)Ray_SetSpriteView);
- engine->RegisterScriptFunction("Raycast::GetSpriteView^1", (void *)Ray_GetSpriteView);
- engine->RegisterScriptFunction("Raycast::SetSpriteFrame^2", (void *)Ray_SetSpriteFrame);
- engine->RegisterScriptFunction("Raycast::GetSpriteFrame^1", (void *)Ray_GetSpriteFrame);
- engine->RegisterScriptFunction("Raycast::SetSpritePic^2", (void *)Ray_SetSpritePic);
- engine->RegisterScriptFunction("Raycast::GetSpritePic^1", (void *)Ray_GetSpritePic);
- engine->RegisterScriptFunction("Raycast::SetSkyBox^1", (void *)Ray_SetSkyBox);
- engine->RegisterScriptFunction("Raycast::SetSpriteAlpha^2", (void *)Ray_SetSpriteAlpha);
- engine->RegisterScriptFunction("Raycast::GetSpriteAlpha^1", (void *)Ray_GetSpriteAlpha);
- engine->RegisterScriptFunction("Raycast::GetSkyBox^1", (void *)Ray_GetSkyBox);
- engine->RegisterScriptFunction("Raycast::SetAmbientLight^1", (void *)Ray_SetAmbientLight);
- engine->RegisterScriptFunction("Raycast::SetAmbientColor^2", (void *)Ray_SetAmbientColor);
- engine->RegisterScriptFunction("Raycast::GetAmbientLight^0", (void *)Ray_GetAmbientLight);
- engine->RegisterScriptFunction("Raycast::GetAmbientWeight^0", (void *)Ray_GetAmbientWeight);
- engine->RegisterScriptFunction("Raycast::GetTileX_At^2", (void *)Ray_GetTileX_At);
- engine->RegisterScriptFunction("Raycast::GetTileY_At^2", (void *)Ray_GetTileY_At);
- engine->RegisterScriptFunction("Raycast::DrawTile^2", (void *)Ray_DrawTile);
- engine->RegisterScriptFunction("Raycast::DrawOntoTile^2", (void *)Ray_DrawOntoTile);
- engine->RegisterScriptFunction("Raycast::SetNoClip^1", (void *)Ray_SetNoClip);
- engine->RegisterScriptFunction("Raycast::GetNoClip^0", (void *)Ray_GetNoClip);
- engine->RegisterScriptFunction("Raycast::GetSpriteScaleX^1", (void *)Ray_GetSpriteScaleX);
- engine->RegisterScriptFunction("Raycast::SetSpriteScaleX^2", (void *)Ray_SetSpriteScaleX);
- engine->RegisterScriptFunction("Raycast::GetSpriteScaleY^1", (void *)Ray_GetSpriteScaleY);
- engine->RegisterScriptFunction("Raycast::SetSpriteScaleY^2", (void *)Ray_SetSpriteScaleY);
- engine->RegisterScriptFunction("Raycast::GetSpriteBlendType^1", (void *)Ray_GetSpriteBlendType);
- engine->RegisterScriptFunction("Raycast::SetSpriteBlendType^2", (void *)Ray_SetSpriteBlendType);
-
-
- engine->RegisterScriptFunction("Raycast::SetFloorAt^3", (void *)Ray_SetFloorAt);
- engine->RegisterScriptFunction("Raycast::SetCeilingAt^3", (void *)Ray_SetCeilingAt);
- engine->RegisterScriptFunction("Raycast::GetCeilingAt^2", (void *)Ray_GetCeilingAt);
- engine->RegisterScriptFunction("Raycast::GetFloorAt^2", (void *)Ray_GetFloorAt);
- engine->RegisterScriptFunction("Raycast::GetLightingAt^2", (void *)Ray_GetLightingAt);
- engine->RegisterScriptFunction("Raycast::SetLightingAt^3", (void *)Ray_SetLightingAt);
- engine->RegisterScriptFunction("Raycast::GetWallHotspot^1", (void *)Ray_GetWallHotspot);
- engine->RegisterScriptFunction("Raycast::GetWallTexture^2", (void *)Ray_GetWallTexture);
- engine->RegisterScriptFunction("Raycast::GetWallSolid^2", (void *)Ray_GetWallSolid);
- engine->RegisterScriptFunction("Raycast::GetWallIgnoreLighting^2", (void *)Ray_GetWallIgnoreLighting);
- engine->RegisterScriptFunction("Raycast::GetWallAlpha^2", (void *)Ray_GetWallAlpha);
- engine->RegisterScriptFunction("Raycast::GetWallBlendType^2", (void *)Ray_GetWallBlendType);
- engine->RegisterScriptFunction("Raycast::SelectTile^3", (void *)Ray_SelectTile);
- engine->RegisterScriptFunction("Raycast::HasSeenTile^2", (void *)Ray_HasSeenTile);
-
- engine->RegisterScriptFunction("LensDistort::SetPos^2", (void *)SetLensPos);
- engine->RegisterScriptFunction("LensDistort::GetX^0", (void *)GetLensX);
- engine->RegisterScriptFunction("LensDistort::GetY^0", (void *)GetLensY);
- engine->RegisterScriptFunction("LensDistort::Set^1", (void *)SetLensDrawn);
- engine->RegisterScriptFunction("LensDistort::IsDrawn^0", (void *)GetLensDrawn);
- engine->RegisterScriptFunction("LensDistort::SetOffsetClamp^1", (void *)SetLensOffsetClamp);
- engine->RegisterScriptFunction("LensDistort::GetOffsetClamp^0", (void *)GetLensOffsetClamp);
- engine->RegisterScriptFunction("LensDistort::GetLevel^0", (void *)GetLensLevel);
- engine->RegisterScriptFunction("LensDistort::SetLevel^1", (void *)GetLensLevel);
- engine->RegisterScriptFunction("LensDistort::Initialize^6", (void *)LensInitialize);
-
- engine->RegisterScriptFunction("Translucence::CreateOverlay^8", (void *)CreateTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::DeleteOverlay^1", (void *)DeleteTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::Move^3", (void *)MoveTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::GetOverlayX^1", (void *)GetTranslucentOverlayX);
- engine->RegisterScriptFunction("Translucence::GetOverlayY^1", (void *)GetTranslucentOverlayY);
- engine->RegisterScriptFunction("Translucence::GetOverlaySprite^1", (void *)GetTranslucentOverlaySprite);
- engine->RegisterScriptFunction("Translucence::GetOverlayLevel^1", (void *)GetTranslucentOverlayLevel);
- engine->RegisterScriptFunction("Translucence::GetOverlayEnabled^1", (void *)GetTranslucentOverlayEnabled);
- engine->RegisterScriptFunction("Translucence::GetOverlayAlpha^1", (void *)GetTranslucentOverlayAlpha);
- engine->RegisterScriptFunction("Translucence::SetOverlayAlpha^2", (void *)SetTranslucentOverlayAlpha);
- engine->RegisterScriptFunction("Translucence::SetOverlayEnabled^2", (void *)SetTranslucentOverlayEnabled);
- engine->RegisterScriptFunction("Translucence::DrawTransSprite^6", (void *)DrawTransSprite);
-
- engine->RegisterScriptFunction("Starfield::GetOverscan^0", (void *)GetStarfieldOverscan);
- engine->RegisterScriptFunction("Starfield::SetOverscan^1", (void *)SetStarfieldOverscan);
- engine->RegisterScriptFunction("Starfield::GetOriginX^0", (void *)GetStarfieldOriginX);
- engine->RegisterScriptFunction("Starfield::GetOriginY^0", (void *)GetStarfieldOriginY);
- engine->RegisterScriptFunction("Starfield::SetDepthMultiplier^1", (void *)SetStarfieldDepthMultiplier);
- engine->RegisterScriptFunction("Starfield::GetDepthMultiplier^0", (void *)GetStarfieldDepthMultiplier);
- engine->RegisterScriptFunction("Starfield::GetMaxStars^0", (void *)GetStarfieldMaxStars);
- engine->RegisterScriptFunction("Starfield::SetStarSpriteScaleBoost^1", (void *)SetStarSpriteScaleBoost);
- engine->RegisterScriptFunction("Starfield::GetStarSpriteScaleBoost^0", (void *)GetStarSpriteScaleBoost);
- engine->RegisterScriptFunction("Starfield::SetStarMaxRadius^2", (void *)SetStarMaxRadius);
- engine->RegisterScriptFunction("Starfield::GetStarMaxRadius^0", (void *)GetStarMaxRadius);
- engine->RegisterScriptFunction("Starfield::GetStarX^1", (void *)GetStarX);
- engine->RegisterScriptFunction("Starfield::GetStarY^1", (void *)GetStarY);
- engine->RegisterScriptFunction("Starfield::GetStarZ^1", (void *)GetStarZ);
- engine->RegisterScriptFunction("Starfield::SetStarPosition^4", (void *)SetStarPosition);
- engine->RegisterScriptFunction("Starfield::RotateStar^4", (void *)RotateStar);
- engine->RegisterScriptFunction("Starfield::SetStarColor^2", (void *)SetStarColor);
- engine->RegisterScriptFunction("Starfield::GetStarColor^1", (void *)GetStarColor);
- engine->RegisterScriptFunction("Starfield::SetStarSprite^2", (void *)SetStarSprite);
- engine->RegisterScriptFunction("Starfield::GetStarSprite^1", (void *)GetStarSprite);
- engine->RegisterScriptFunction("Starfield::SetStarSpriteRange^3", (void *)SetStarSpriteRange);
- engine->RegisterScriptFunction("Starfield::Initialize^2", (void *)InitializeStars);
- engine->RegisterScriptFunction("Starfield::Iterate^1", (void *)IterateStars);
- engine->RegisterScriptFunction("Starfield::Draw^2", (void *)DrawStars);
- engine->RegisterScriptFunction("Starfield::SetOriginPoint^2", (void *)SetStarsOriginPoint);
-
- engine->RegisterScriptFunction("Plasma::DoFire^8", (void *)DoFire);
- engine->RegisterScriptFunction("Plasma::SetPlasmaType^5", (void *)SetPlasmaType);
- engine->RegisterScriptFunction("Plasma::ResetPlasmaSettings^0", (void *)ResetPlasmaSettings);
- engine->RegisterScriptFunction("Plasma::DrawPlasma^3", (void *)DrawPlasma);
- engine->RegisterScriptFunction("Plasma::SetRootType^1", (void *)SetPlasmaRootType);
- engine->RegisterScriptFunction("Plasma::GetRootType^0", (void *)GetPlasmaRootType);
-
- engine->RegisterScriptFunction("Reflections::Set^1", (void *)SetReflections);
- engine->RegisterScriptFunction("Reflections::IsReflecting^0", (void *)IsReflectionsOn);
- engine->RegisterScriptFunction("Reflections::SetCharacterReflected^2", (void *)SetCharacterReflected);
- engine->RegisterScriptFunction("Reflections::GetCharacterReflected^1", (void *)GetCharacterReflected);
- engine->RegisterScriptFunction("Reflections::SetObjectReflected^2", (void *)SetObjectReflected);
- engine->RegisterScriptFunction("Reflections::GetObjectReflected^1", (void *)GetObjectReflected);
- engine->RegisterScriptFunction("Reflections::ReplaceCharacterReflectionView^2", (void *)ReplaceCharacterReflectionView);
- engine->RegisterScriptFunction("Reflections::SetObjectReflectionIgnoreScaling^2", (void *)SetObjectReflectionIgnoreScaling);
- engine->RequestEventHook(AGSE_PRESCREENDRAW);
- engine->RequestEventHook(AGSE_PREGUIDRAW);
- engine->RequestEventHook(AGSE_POSTSCREENDRAW);
- engine->RequestEventHook(AGSE_SAVEGAME);
- engine->RequestEventHook(AGSE_RESTOREGAME);
- engine->RequestEventHook(AGSE_ENTERROOM);
- stars = new starstype [MAX_STARS];
- Starfield.maxstars = MAX_STARS;
- Starfield.depthmultiplier = 256;
- Starfield.speed = 0.5;
- Starfield.originx = 160;
- Starfield.originy = 100;
- Reflection.Characters = new charrefopt [engine->GetNumCharacters()]();
- lens = new LensDistort [LENS_WIDTH * LENS_WIDTH]();
- //PreMultiply_Alphas ();
- plasmaroottype = 0;
- Make_Sin_Lut();
- Init_Raycaster();
-}
-
-void AGSPalRender::AGS_EngineShutdown() {
- // no work to do here - but if we had created any dynamic sprites,
- // we should delete them here
- delete[] Reflection.Characters;
- delete[] Reflection.Objects;
- //QuitCleanup();
-}
-
-NumberPtr AGSPalRender::AGS_EngineOnEvent(int event, NumberPtr data) {
- if (event == AGSE_PRESCREENDRAW && clutslot > 0) {
- if (drawreflections) {
- int32 sh, sw = 0;
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- reflectionmap = new long[sw * sh]();
- rcolormap = engine->CreateBlankBitmap(sw, sh, 8);
- ralphamap = engine->CreateBlankBitmap(sw, sh, 8);
- for (int i = 0; i < engine->GetNumCharacters(); i++) {
- if (Reflection.Characters[i].reflect == 0) continue;
- AGSCharacter *tempchar = engine->GetCharacter(i);
- if (tempchar->room != engine->GetCurrentRoom()) continue; //if character isn't even in the room, go to next iteration.
- int32 vx = tempchar->x;
- int32 vy = tempchar->y;
- engine->RoomToViewport(&vx, &vy);
- AGSViewFrame *vf = engine->GetViewFrame(tempchar->view + 1, tempchar->loop, tempchar->frame);
- int w = engine->GetSpriteWidth(vf->pic);
- int h = engine->GetSpriteHeight(vf->pic);
- vx = vx - (w / 2);
- int32 vxmax = vx + w;
- int32 vymax = vy + h;
- if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
- DrawReflections(i, 0);
- }
- for (int i = 0; i < engine->GetNumObjects(); i++) {
- if (Reflection.Objects[i].reflect == 0) continue;
- AGSObject *tempobj = engine->GetObject(i);
- if (!tempobj->on) continue;
- int32 vx = tempobj->x;
- int32 vy = tempobj->baseline - tempobj->y;
- engine->RoomToViewport(&vx, &vy);
- int32 w = engine->GetSpriteWidth(tempobj->num);
- int32 h = engine->GetSpriteHeight(tempobj->num);
- int32 vxmax = vx + w;
- int32 vymax = vy + h;
- if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
- DrawReflections(i, 1);
- }
- BITMAP *virtsc = engine->GetVirtualScreen();
- unsigned char **screenbuffer = engine->GetRawBitmapSurface(virtsc);
- unsigned char **colorbuffer = engine->GetRawBitmapSurface(rcolormap);
- unsigned char **alphabuffer = engine->GetRawBitmapSurface(ralphamap);
- for (int y = 0; y < sh; y++)
- for (int x = 0; x < sw; x++)
- screenbuffer[y][x] = Mix::MixColorAlpha(colorbuffer[y][x], screenbuffer[y][x], alphabuffer[y][x]);
- engine->ReleaseBitmapSurface(rcolormap);
- engine->ReleaseBitmapSurface(ralphamap);
- engine->ReleaseBitmapSurface(virtsc);
- engine->FreeBitmap(rcolormap);
- engine->FreeBitmap(ralphamap);
- delete [] reflectionmap;
- }
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 0) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 0) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_PREGUIDRAW && clutslot > 0) {
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 1) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 2) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_POSTSCREENDRAW && clutslot > 0) {
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 3) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 2) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 4) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_SAVEGAME) {
- for (int i = 0; i < MAX_OVERLAYS; ++i) {
- engine->FWrite(&overlay[i].sprite, sizeof(int), data);
- engine->FWrite(&overlay[i].spritemask, sizeof(int), data);
- engine->FWrite(&overlay[i].x, sizeof(int), data);
- engine->FWrite(&overlay[i].y, sizeof(int), data);
- engine->FWrite(&overlay[i].level, sizeof(int), data);
- engine->FWrite(&overlay[i].trans, sizeof(int), data);
- engine->FWrite(&overlay[i].blendtype, sizeof(int), data);
- engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
- }
- engine->FWrite(&clutslot, sizeof(int), data);
- engine->FWrite(&drawreflections, sizeof(int), data);
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data);
- engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data);
- engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&sprite[j].x, sizeof(double), data);
- engine->FWrite(&sprite[j].y, sizeof(double), data);
- engine->FWrite(&sprite[j].texture, sizeof(int), data);
- engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data);
- engine->FWrite(&sprite[j].uDivW, sizeof(double), data);
- engine->FWrite(&sprite[j].uDivH, sizeof(double), data);
- engine->FWrite(&sprite[j].vMove, sizeof(double), data);
- engine->FWrite(&sprite[j].hMove, sizeof(double), data);
- engine->FWrite(&sprite[j].objectinteract, sizeof(char), data);
- engine->FWrite(&sprite[j].view, sizeof(int), data);
- engine->FWrite(&sprite[j].frame, sizeof(int), data);
- engine->FWrite(&sprite[j].angle, sizeof(int), data);
- }
- for (int j = 0; j < 256; ++j) {
- for (int k = 0; k < 4; ++k) {
- engine->FWrite(&wallData[j].texture[k], sizeof(int), data);
- engine->FWrite(&wallData[j].solid[k], sizeof(int), data);
- engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data);
- engine->FWrite(&wallData[j].alpha[k], sizeof(int), data);
- engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data);
- engine->FWrite(&wallData[j].mask[k], sizeof(int), data);
- }
- engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data);
- }
- engine->FWrite(&raycastOn, sizeof(bool), data);
- engine->FWrite(&heightmapOn, sizeof(bool), data);
- engine->FWrite(&posX, sizeof(double), data);
- engine->FWrite(&posY, sizeof(double), data);
- engine->FWrite(&dirX, sizeof(double), data);
- engine->FWrite(&dirY, sizeof(double), data);
- engine->FWrite(&planeX, sizeof(double), data);
- engine->FWrite(&planeY, sizeof(double), data);
- engine->FWrite(&moveSpeed, sizeof(double), data);
- engine->FWrite(&rotSpeed, sizeof(double), data);
- if (raycastOn) { //If the raycaster is active, we have additional data to save.
- for (int i = 0; i < mapWidth; ++i)
- for (int j = 0; j < mapHeight; ++j) {
- engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data);
- engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data);
- engine->FWrite(&ceilingMap [i][j], sizeof(int), data);
- engine->FWrite(&floorMap [i][j], sizeof(int), data);
- engine->FWrite(&heightMap [i][j], sizeof(int), data);
- }
- }
- engine->FWrite(&textureSlot, sizeof(int), data);
- engine->FWrite(&skybox, sizeof(int), data);
- engine->FWrite(&ambientlight, sizeof(int), data);
- }
- if (event == AGSE_RESTOREGAME) {
-
-
- for (int i = 0; i < MAX_OVERLAYS; ++i) {
- engine->FRead(&overlay[i].sprite, sizeof(int), data);
- engine->FRead(&overlay[i].spritemask, sizeof(int), data);
- engine->FRead(&overlay[i].x, sizeof(int), data);
- engine->FRead(&overlay[i].y, sizeof(int), data);
- engine->FRead(&overlay[i].level, sizeof(int), data);
- engine->FRead(&overlay[i].trans, sizeof(int), data);
- engine->FRead(&overlay[i].blendtype, sizeof(int), data);
- engine->FRead(&overlay[i].enabled, sizeof(bool), data);
- }
- engine->FRead(&clutslot, sizeof(int), data);
- engine->FRead(&drawreflections, sizeof(int), data);
- for (int j = 0; j < 256; ++j) {
- engine->FRead(&cycle_remap[j], sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Objective Palette, for palette mixing.
- engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data);
- engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data);
- engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Raycaster Sprite struct, 256 instances.
- engine->FRead(&sprite[j].x, sizeof(double), data);
- engine->FRead(&sprite[j].y, sizeof(double), data);
- engine->FRead(&sprite[j].texture, sizeof(int), data);
- engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data);
- engine->FRead(&sprite[j].uDivW, sizeof(double), data);
- engine->FRead(&sprite[j].uDivH, sizeof(double), data);
- engine->FRead(&sprite[j].vMove, sizeof(double), data);
- engine->FRead(&sprite[j].hMove, sizeof(double), data);
- engine->FRead(&sprite[j].objectinteract, sizeof(char), data);
- engine->FRead(&sprite[j].view, sizeof(int), data);
- engine->FRead(&sprite[j].frame, sizeof(int), data);
- engine->FRead(&sprite[j].angle, sizeof(int), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Raycaster wall type data.
- for (int k = 0; k < 4; ++k) {
- engine->FRead(&wallData[j].texture[k], sizeof(int), data);
- engine->FRead(&wallData[j].solid[k], sizeof(int), data);
- engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data);
- engine->FRead(&wallData[j].alpha[k], sizeof(int), data);
- engine->FRead(&wallData[j].blendtype[k], sizeof(int), data);
- engine->FRead(&wallData[j].mask[k], sizeof(int), data);
- }
- engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data);
- }
- //Delete worldmap data if it exists.
- engine->FRead(&raycastOn, sizeof(bool), data);
- engine->FRead(&heightmapOn, sizeof(bool), data);
- engine->FRead(&posX, sizeof(double), data);
- engine->FRead(&posY, sizeof(double), data);
- engine->FRead(&dirX, sizeof(double), data);
- engine->FRead(&dirY, sizeof(double), data);
- engine->FRead(&planeX, sizeof(double), data);
- engine->FRead(&planeY, sizeof(double), data);
- engine->FRead(&moveSpeed, sizeof(double), data);
- engine->FRead(&rotSpeed, sizeof(double), data);
- if (raycastOn) { //If the raycaster is currently running, we have additional data to load.
- for (int i = 0; i < mapWidth; ++i) {
- for (int j = 0; j < mapHeight; ++j) {
- engine->FRead(&worldMap [i][j], sizeof(unsigned char), data);
- engine->FRead(&lightMap [i][j], sizeof(unsigned char), data);
- engine->FRead(&ceilingMap [i][j], sizeof(int), data);
- engine->FRead(&floorMap [i][j], sizeof(int), data);
- engine->FRead(&heightMap [i][j], sizeof(int), data);
- seenMap [i][j] = 0;
- }
- }
-
- //Reinitialize all the buffers and stuff.
-
- }
- engine->FRead(&textureSlot, sizeof(int), data);
- if (textureSlot) MakeTextures(textureSlot);
- engine->FRead(&skybox, sizeof(int), data);
- engine->FRead(&ambientlight, sizeof(int), data);
- LoadCLUT(clutslot);
- }
- if (event == AGSE_ENTERROOM) {
- ResetRemapping();
- delete[] Reflection.Objects;
- Reflection.Objects = new objrefopt [engine->GetNumObjects()]();
- }
- return 0;
-}
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ags/lib/allegro.h"
+#include "ags/plugins/ags_pal_render/ags_pal_render.h"
+#include "ags/plugins/ags_pal_render/pal_render.h"
+#include "ags/plugins/ags_pal_render/raycast.h"
+#include "ags/ags.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define MAX_OVERLAYS 128
+#define MAX_STARS 1024
+#define MAX_DEPTH 64
+
+#define PI (3.1415926535f)
+#define HALF_PI (0.5f * PI)
+#define TWO_PI (2.0f * PI)
+#define TWO_PI_INV (1.0f / TWO_PI)
+
+const float halfpi = (0.5f * PI);
+const float twopi = (2.0f * PI);
+const float twopi_inv = (1.0f / TWO_PI);
+const float pisquared = PI * PI;
+const float picubed = PI * PI * PI;
+
+IAGSEngine *engine;
+
+//unsigned char clut[256][256];
+unsigned char clut[65536];
+
+struct transoverlaytype {
+ int sprite;
+ int spritemask;
+ int blendtype;
+ int x;
+ int y;
+ int trans;
+ int level;
+ bool enabled;
+} overlay[MAX_OVERLAYS];
+
+int clutslot;
+int drawreflections;
+unsigned char cycle_remap [256];
+
+struct starstype {
+ float x;
+ float y;
+ float z;
+ unsigned char color;
+ long sprite;
+ int maxrad;
+ int scaleboost;
+};
+starstype *stars;
+
+struct starsoptions {
+ float speed;
+ int maxstars;
+ int depthmultiplier;
+ int originx;
+ int originy;
+ int overscan;
+} Starfield;
+long *reflectionmap;
+BITMAP *rcolormap;
+BITMAP *ralphamap;
+
+struct charrefopt {
+ char reflect;
+ int replaceview;
+};
+
+struct objrefopt {
+ char reflect;
+ char ignorescaling;
+};
+
+struct reflectionopt {
+ charrefopt *Characters;
+ objrefopt *Objects;
+ int blendslot;
+ int blendamount;
+} Reflection;
+
+int dummy;
+
+#define LENS_WIDTH 150
+
+struct LensDistort {
+ int xoffset;
+ int yoffset;
+};
+
+LensDistort *lens;
+struct LensOpt {
+ bool draw;
+ int lenswidth;
+ int lenszoom;
+ int level;
+ int x;
+ int y;
+ int clampoffset;
+} LensOption;
+
+const int alphamultiply [4096] = {
+//#include "alphamultiply.txt"
+};
+float rot_sine_LUT[360];
+float rot_cos_LUT[360];
+
+BITMAP *backgroundimage;
+
+PALSTRUCT objectivepal[256];
+int bgimgspr;
+
+void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) {
+ objectivepal[index].r = r;
+ objectivepal[index].b = b;
+ objectivepal[index].g = g;
+}
+
+int ReadObjectivePaletteR(unsigned char index) {
+ return objectivepal[index].r;
+}
+
+int ReadObjectivePaletteB(unsigned char index) {
+ return objectivepal[index].b;
+}
+int ReadObjectivePaletteG(unsigned char index) {
+ return objectivepal[index].g;
+}
+
+
+#define SQRT_MAGIC_F 0x5f3759df
+float q3sqrt(const float x) {
+ const float xhalf = 0.5f * x;
+
+ union { // get bits for floating value
+ float x;
+ int i;
+ } u;
+ u.x = x;
+ u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
+ return x * u.x * (1.5f - xhalf * u.x * u.x); // Newton step, repeating increases accuracy
+}
+
+void Make_Sin_Lut() {
+ for (int angle = 0; angle < 360; angle++) {
+ double rad = (angle * PI) / 180.0;
+ rot_sine_LUT [angle] = static_cast<float>(sin(rad));
+ rot_cos_LUT [angle] = static_cast<float>(cos(rad));
+ }
+}
+
+/*
+void PreMultiply_Alphas () //Ha ha, this isn't the kind of premultiplcation you're thinking of.
+{
+ for (int y=0;y<64;y++)
+ for (int x=0;x<64;x++)
+ alphamultiply [y*64+x] = y*x;
+}
+*/
+
+int GetModifiedBackgroundImage() {
+ return bgimgspr;
+}
+
+unsigned short root(unsigned short x) {
+ unsigned short a, b;
+ b = x;
+ a = x = 0x3f;
+ x = b / x;
+ a = x = (x + a) >> 1;
+ x = b / x;
+ a = x = (x + a) >> 1;
+ x = b / x;
+ x = (x + a) >> 1;
+ return (x);
+}
+
+
+float Hill(float x) {
+ const float a0 = 1.0f;
+ const float a2 = 2.0f / PI - 12.0f / (pisquared);
+ const float a3 = 16.0f / (picubed) - 4.0f / (pisquared);
+ const float xx = x * x;
+ const float xxx = xx * x;
+
+ return a0 + a2 * xx + a3 * xxx;
+}
+
+float FastSin(float x) {
+ // wrap x within [0, TWO_PI)
+ const float a = x * twopi_inv;
+ x -= static_cast<int>(a) * twopi;
+ if (x < 0.0f)
+ x += twopi;
+
+ // 4 pieces of hills
+ if (x < halfpi)
+ return Hill(halfpi - x);
+ else if (x < PI)
+ return Hill(x - halfpi);
+ else if (x < 3.0f * halfpi)
+ return -Hill(3.0f * halfpi - x);
+ else
+ return -Hill(x - 3.0f * halfpi);
+}
+
+float FastCos(float x) {
+ return FastSin(x + halfpi);
+}
+
+FLOAT_RETURN_TYPE AGSFastSin(SCRIPT_FLOAT(x)) {
+ INIT_SCRIPT_FLOAT(x);
+ x = FastSin(x);
+ RETURN_FLOAT(x);
+}
+
+FLOAT_RETURN_TYPE AGSFastCos(SCRIPT_FLOAT(x)) {
+ INIT_SCRIPT_FLOAT(x);
+ x = FastSin(x + halfpi);
+ RETURN_FLOAT(x);
+}
+
+
+void DrawLens(int ox, int oy) {
+ int32 sh, sw = 0;
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen.");
+ BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8);
+ unsigned char **vScreen = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite);
+ int radius = LensOption.lenswidth >> 1;
+ for (int y = 0; y < LensOption.lenswidth; y++) {
+ int ypos = y * LensOption.lenswidth;
+ for (int x = 0; x < LensOption.lenswidth; x++) {
+ int lenspos = ypos + x;
+ int coffx = lens[lenspos].xoffset;
+ int coffy = lens[lenspos].yoffset;
+ if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) {
+ lensarray[y][x] = vScreen[oy + coffy][ox + coffx];
+ //vScreen[oy+coffy][ox+coffx] = ABS(coffy);
+ }
+ }
+ }
+ /*
+ for (int y=0;y<LensOption.lenswidth;y++)
+ {
+ int ypos = y*LensOption.lenswidth;
+ for (int x=0;x<LensOption.lenswidth;x++)
+ {
+ if (oy+y > 0 && oy+y < sh && ox+x > 0 && ox+x < sw)
+ {
+ vScreen[oy+y][ox+x] = lensarray[y][x];
+ }
+ }
+ }
+ */
+ int radsq = radius * radius;
+ for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
+ int cysq = cy * cy;
+ for (int cx = -radius; cx <= radius; cx++) {
+ int cxsq = cx * cx;
+ int dx = cx + ox;
+ int dy = cy + oy;
+ if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) {
+ //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong");
+ vScreen[dy][dx] = lensarray[cy + radius][cx + radius];
+ }
+ }
+ }
+
+ engine->ReleaseBitmapSurface(lenswrite);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->FreeBitmap(lenswrite);
+}
+
+void SetLensPos(int x, int y) {
+ LensOption.x = x;
+ LensOption.y = y;
+}
+
+int GetLensX() {
+ return LensOption.x;
+}
+
+int GetLensY() {
+ return LensOption.y;
+}
+
+void SetLensDrawn(int toggle) {
+ if (toggle > 0) LensOption.draw = 1;
+ else LensOption.draw = 0;
+}
+
+int GetLensDrawn() {
+ return LensOption.draw;
+}
+
+void SetLensOffsetClamp(int clamp) {
+ if (clamp < 0) LensOption.clampoffset = LensOption.lenswidth;
+ else LensOption.clampoffset = clamp;
+}
+
+int GetLensOffsetClamp() {
+ return LensOption.clampoffset;
+}
+
+int GetLensLevel() {
+ return LensOption.level;
+}
+
+void SetLensLevel(int level) {
+ if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
+ else LensOption.level = level;
+}
+
+void LensInitialize(int width, int zoom, int lensx, int lensy, int level, int clamp = -1) {
+ int32 sw, sh, radius;
+ if (width < 1) engine->AbortGame("Invalid lens dimension!");
+ radius = width >> 1;
+ lens = new LensDistort [width * width]();
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ int radsq = radius * radius;
+ int zoomsq = zoom * zoom;
+ for (int y = 0; y < radius; y++) {
+ int ysq = y * y;
+ for (int x = 0; x < radius; x++) {
+ int lx, ly;
+ int xsq = x * x;
+ if ((xsq + ysq) < (radsq)) {
+ float shift = zoom / sqrt((float)(zoomsq - (xsq + ysq - radsq)));
+ lx = (int)(x * shift - x);
+ ly = (int)(y * shift - y);
+ } else {
+ lx = 0;
+ ly = 0;
+ }
+ lens[(radius - y)*width + (radius - x)].xoffset = lx;
+ lens[(radius - y)*width + (radius - x)].yoffset = ly;
+ lens[(radius + y)*width + (radius + x)].xoffset = -lx;
+ lens[(radius + y)*width + (radius + x)].yoffset = -ly;
+ lens[(radius + y)*width + (radius - x)].xoffset = lx;
+ lens[(radius + y)*width + (radius - x)].yoffset = -ly;
+ lens[(radius - y)*width + (radius + x)].xoffset = -lx;
+ lens[(radius - y)*width + (radius + x)].yoffset = ly;
+ }
+ }
+ LensOption.lenswidth = width;
+ LensOption.lenszoom = zoom;
+ if (clamp < 0) LensOption.clampoffset = width;
+ else LensOption.clampoffset = clamp;
+ LensOption.x = lensx;
+ LensOption.y = lensy;
+ if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
+ else LensOption.level = level;
+}
+
+void ResetRemapping() {
+ for (int j = 0; j < 256; ++j) {
+ cycle_remap [j] = j;
+ }
+}
+
+#define MAX_PLASMA_COMPLEXITY 4
+int plasmatype[MAX_PLASMA_COMPLEXITY];
+int plasmadata [MAX_PLASMA_COMPLEXITY];
+int plasmadata2 [MAX_PLASMA_COMPLEXITY];
+int plasmadata3 [MAX_PLASMA_COMPLEXITY];
+int plasmaroottype;
+
+
+void SetPlasmaRootType(int real) {
+ if (real) plasmaroottype = 1;
+ else plasmaroottype = 0;
+}
+
+int GetPlasmaRootType() {
+ return plasmaroottype;
+}
+
+void SetPlasmaType(int component, int type, int data, int data2, int data3) {
+ if (component >= MAX_PLASMA_COMPLEXITY) engine->AbortGame("Plasma too complex!");
+ else {
+ plasmatype [component] = type;
+ plasmadata [component] = data;
+ plasmadata2[component] = data2;
+ plasmadata3[component] = data3;
+ }
+
+ //0 = None.
+ //1 = Horizontal Bars (data=width)
+ //2 = Vertical Bars (data=width)
+ //3 = Circle (data=x,data2=y,data3=width)
+ //4 = Diagonal Bars (data=width)
+}
+
+void ResetPlasmaSettings() {
+ int i = 0;
+ while (i < MAX_PLASMA_COMPLEXITY) {
+ plasmatype [i] = 0;
+ plasmadata [i] = 0;
+ plasmadata2[i] = 0;
+ plasmadata3[i] = 0;
+ i++;
+ }
+}
+
+void DrawPlasma(int slot, int palstart, int palend) {
+ BITMAP *plasmaspr = engine->GetSpriteGraphic(slot);
+ if (!plasmaspr) engine->AbortGame("Plasma: Not a sprite I can load.");
+ int32 w, h, basecol, range = 0;
+ if (palend > palstart) {
+ range = palend - palstart;
+ basecol = palstart;
+ } else {
+ range = palstart - palend;
+ basecol = palend;
+ }
+ engine->GetBitmapDimensions(plasmaspr, &w, &h, nullptr);
+ unsigned char **plasmarray = engine->GetRawBitmapSurface(plasmaspr);
+ double frange = range / 2.0;
+ int complex = 0;
+ int color = 0;
+ int i = 0;
+ while (i < MAX_PLASMA_COMPLEXITY) {
+ if (plasmatype[i] > 0) complex++;
+ i++;
+ }
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ color = 0;
+ for (int p = 0; p < MAX_PLASMA_COMPLEXITY; p++) {
+ if (plasmatype[p] == 1) { //1 = Horizontal Bars (data=width)
+ color += int(frange + (frange * FastSin(y / (float)plasmadata[p])));
+ } else if (plasmatype[p] == 2) { //2 = Vertical Bars (data=width)
+ color += int(frange + (frange * FastSin(x / (float)plasmadata[p])));
+ } else if (plasmatype[p] == 3) { //3 = Circle (data=x,data2=y,data3=width)
+ int cx, cy = 0;
+ cx = plasmadata [p];
+ cy = plasmadata2 [p];
+ if (plasmaroottype == 1) color += int(frange + (frange * FastSin(q3sqrt((float)((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
+ else color += int(frange + (frange * FastSin(root(((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
+ } else if (plasmatype[p] == 4) { //4 = Diagonal Bars (data=width)
+ color += int(frange + (frange * FastSin((x + y) / (float)plasmadata[p])));
+ }
+ }
+ if (color > 0 && complex > 0) color = color / complex;
+ plasmarray[y][x] = static_cast<unsigned char>(basecol + color);
+ }
+ }
+ engine->ReleaseBitmapSurface(plasmaspr);
+ engine->NotifySpriteUpdated(slot);
+}
+
+void DoFire(int spriteId, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) {
+ BITMAP *firespr = engine->GetSpriteGraphic(masksprite);
+ BITMAP *firecolorspr = engine->GetSpriteGraphic(spriteId);
+ BITMAP *seedspr;
+ int32 w, h = 0;
+ int range, basecol, dir = 0;
+ if (palend > palstart) {
+ range = palend - palstart;
+ basecol = palstart;
+ dir = 1;
+ } else {
+ range = palstart - palend;
+ basecol = palend;
+ dir = -1;
+ }
+ int divider = 256 / range;
+ engine->GetBitmapDimensions(firespr, &w, &h, nullptr);
+ unsigned char **fire = engine->GetRawBitmapSurface(firespr);
+ unsigned char **color = engine->GetRawBitmapSurface(firecolorspr);
+ int sparky = 0;
+ //srand(time(NULL));
+ for (int y = 0; y < h - 1; y++) {
+ if ((int)::AGS::g_vm->getRandomNumber(9) > 7 - windspeed) { //Wind right
+ for (int x = w - 1; x > 1; x--) {
+ fire[y][x] = fire[y][x - 1];
+ }
+ } else if ((int)::AGS::g_vm->getRandomNumber(9) > 7 + windspeed) { // wind left
+ for (int x = 0; x < w - 1; x++) {
+ fire[y][x] = fire[y][x + 1];
+ }
+ }
+ }
+ for (int x = 0; x < w; x++) {
+ sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
+ if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
+ ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
+ fire[h - sparky][x] = 255;
+ sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
+ if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
+ ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
+ fire[h - sparky][x] = 0;
+ }
+ if (seed == 0) {
+ for (int x = 0; x < w; x++)
+ fire[h - 1][x] = 255;
+ for (int x = 0; x < w; x++)
+ fire[h - 2][x] = ::AGS::g_vm->getRandomNumber(255);
+ } else if (seed > 0) {
+ seedspr = engine->GetSpriteGraphic(seed);
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ engine->SetVirtualScreen(firespr);
+ engine->BlitBitmap(0, 0, seedspr, 1);
+ engine->SetVirtualScreen(virtsc);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->ReleaseBitmapSurface(seedspr);
+ engine->NotifySpriteUpdated(spriteId);
+ engine->NotifySpriteUpdated(masksprite);
+ }
+
+ for (int y = 0; y < h - 1; y++) {
+ for (int x = 0; x < w; x++) {
+ fire[y][x] =
+ ((fire[(y + 1) % h][(x - 1 + w) % w]
+ + fire[(y + 1) % h][(x) % w]
+ + fire[(y + 1) % h][(x + 1) % w]
+ + fire[(y + 2) % h][(x) % w])
+ * 100) / (400 + (100 - strength));
+ if (fire[y][x] < cutoff) fire[y][x] = 0;
+ //if (fire[y][x] ==255) color [y][x] = palend;
+ else color [y][x] = static_cast<unsigned char>(basecol + (fire[y][x] / divider) * dir);
+ }
+ }
+ engine->ReleaseBitmapSurface(firespr);
+ engine->ReleaseBitmapSurface(firecolorspr);
+ engine->NotifySpriteUpdated(spriteId);
+ engine->NotifySpriteUpdated(masksprite);
+}
+
+/*
+unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha)
+{
+ //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette ();
+ int i=0;
+ int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
+ int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
+ int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
+ //unsigned char ralpha = alpha>>2;
+ //unsigned char invralpha = 64-ralpha;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //int out_r = alphamultiply[(palette[fg].r>>1)][ralpha] + alphamultiply[(palette[bg].r>>1)][(invralpha)];
+ //int out_g = alphamultiply[(palette[fg].g)][ralpha] + alphamultiply[(palette[bg].g)][(invralpha)];
+ //int out_b = alphamultiply[(palette[fg].b>>1)][ralpha] + alphamultiply[(palette[bg].b>>1)][(invralpha)];
+ out_r = (out_r + 1 + (out_r >> 8)) >> 8;
+ out_g = (out_g + 1 + (out_g >> 8)) >> 8;
+ out_b = (out_b + 1 + (out_b >> 8)) >> 8;
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+
+unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha)
+{
+ //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette ();
+ int i=0;
+ int add_r,add_b,add_g = 0;
+ char ralpha = alpha>>2;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //add_r = (((palette[fg].r>>1) * (alpha))>>8);
+ //add_b = (((palette[fg].b>>1) * (alpha))>>8);
+ //add_g = (((palette[fg].g) * (alpha))>>8);
+ add_r = ((alphamultiply[(palette[fg].r>>1)*64+ralpha])>>6);
+ add_b = ((alphamultiply[(palette[fg].b>>1)*64+ralpha])>>6);
+ add_g = ((alphamultiply[(palette[fg].g )*64+ralpha])>>6);
+ int out_r = min(31,(palette[bg].r>>1) + add_r);
+ int out_g = min(63, palette[bg].g + add_g);
+ int out_b = min(31,(palette[bg].b>>1) + add_b);
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+*/
+unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b) {
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ int i = ((r << 11) | (g << 5) | b);
+ unsigned char (*clutp) = clut;
+ unsigned char result = *(clutp + i);
+ result = cycle_remap [result]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+
+void CycleRemap(int start, int end) {
+ if (end > start) {
+ // Rotate left
+ int wraparound = cycle_remap [start];
+ for (; start < end; ++start) {
+ cycle_remap [start] = cycle_remap [start + 1];
+ }
+ cycle_remap [end] = wraparound;
+ } else if (end < start) {
+ // Rotate right
+ int wraparound = cycle_remap [start];
+ for (; start > end; --start) {
+ cycle_remap [start] = cycle_remap [start - 1];
+ }
+ cycle_remap [end] = wraparound;
+
+ }
+}
+
+unsigned char GetRemappedSlot(unsigned char slot) {
+ return cycle_remap [slot];
+}
+
+int LoadCLUT(int slot) {
+ if (engine->GetSpriteWidth(slot) != 256 || engine->GetSpriteHeight(slot) != 256) return 1;
+ BITMAP *clutimage = engine->GetSpriteGraphic(slot);
+ unsigned char **clutarray = engine->GetRawBitmapSurface(clutimage);
+ for (int y = 0; y < 256; y++) {
+ for (int x = 0; x < 256; x++) {
+ clut[y * 256 + x] = clutarray[y][x];
+ }
+ }
+ clutslot = slot;
+ engine->ReleaseBitmapSurface(clutimage);
+ return 0;
+}
+
+void SetReflections(int toggle) {
+ drawreflections = toggle;
+}
+
+int IsReflectionsOn() {
+ return drawreflections;
+}
+
+int GetLuminosityFromPalette(int slot) {
+ AGSColor *pal = engine->GetPalette();
+ int lum = (pal[slot].r +
+ pal[slot].r +
+ pal[slot].r +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].b) >> 3;
+ return lum;
+}
+
+
+
+void SetStarsOriginPoint(int x, int y) {
+ Starfield.originx = x;
+ Starfield.originy = y;
+}
+void InitializeStars(int slot, int maxstars) {
+ int32 sw, sh = 0;
+ BITMAP *canvas = engine->GetSpriteGraphic(slot);
+ engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
+ Starfield.maxstars = maxstars;
+ Starfield.overscan = 20;
+ stars = new starstype [Starfield.maxstars];
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)(MAX_DEPTH);
+ stars[i].color = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 240);
+ stars[i].sprite = 0;
+ stars[i].maxrad = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 5);
+ }
+}
+
+void IterateStars(int slot) {
+ long sw, sh = 0;
+ sw = engine->GetSpriteWidth(slot);
+ sh = engine->GetSpriteHeight(slot);
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ stars[i].z -= Starfield.speed;
+ //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
+ float k = Starfield.depthmultiplier / stars[i].z;
+ int px = static_cast<int>(stars[i].x * k + Starfield.originx);
+ int py = static_cast<int>(stars[i].y * k + Starfield.originy);
+ if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)MAX_DEPTH;
+ //stars[i].color = (rand () %240);
+ }
+ }
+}
+int GetStarfieldOverscan() {
+ return Starfield.overscan;
+}
+void SetStarfieldOverscan(int overscan) {
+ Starfield.overscan = overscan;
+}
+
+int GetStarfieldOriginX() {
+ return Starfield.originx;
+}
+
+int GetStarfieldOriginY() {
+ return Starfield.originy;
+}
+
+void SetStarfieldDepthMultiplier(int multi) {
+ Starfield.depthmultiplier = multi;
+}
+
+int GetStarfieldDepthMultiplier() {
+ return Starfield.depthmultiplier;
+}
+
+int GetStarfieldMaxStars() {
+ return Starfield.maxstars;
+}
+
+void SetStarSpriteScaleBoost(int star, int boost) {
+ stars[star].scaleboost = boost;
+}
+
+int GetStarSpriteScaleBoost(int star) {
+ return stars[star].scaleboost;
+}
+
+void SetStarMaxRadius(int star, int radius) {
+ stars[star].maxrad = radius;
+}
+
+int GetStarMaxRadius(int star) {
+ return stars[star].maxrad;
+}
+
+void RotateStar(int star, int angle, int px, int py) {
+ float rsin = rot_sine_LUT[angle];
+ float rcos = rot_cos_LUT[angle];
+ float fPx = (float)px;
+ float fPy = (float)py;
+ float x1 = 0, y1 = 0, xRot = 0, yRot = 0;
+ int i = star;
+ x1 = stars[i].x;
+ y1 = stars[i].y;
+ xRot = fPx + rcos * (x1 - fPx) - rsin * (y1 - fPy);
+ yRot = fPy + rsin * (x1 - fPx) + rcos * (y1 - fPy);
+ stars[i].x = xRot;
+ stars[i].y = yRot;
+ i++;
+}
+
+FLOAT_RETURN_TYPE GetStarX(int i) {
+ float starx = (float)stars[i].x;
+ RETURN_FLOAT(starx);
+}
+
+FLOAT_RETURN_TYPE GetStarY(int i) {
+ float stary = (float)stars[i].y;
+ RETURN_FLOAT(stary);
+}
+
+FLOAT_RETURN_TYPE GetStarZ(int i) {
+ float starz = (float)stars[i].z;
+ RETURN_FLOAT(starz);
+}
+
+void SetStarPosition(int star, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), SCRIPT_FLOAT(z)) {
+ INIT_SCRIPT_FLOAT(x);
+ INIT_SCRIPT_FLOAT(y);
+ INIT_SCRIPT_FLOAT(z);
+ stars[star].x = x;
+ stars[star].y = y;
+ stars[star].z = z;
+}
+
+void SetStarColor(int star, unsigned char color) {
+ stars[star].color = color;
+}
+
+unsigned char GetStarColor(int star) {
+ return stars[star].color;
+}
+
+void SetStarSprite(int star, int slot) {
+ stars[star].sprite = slot;
+}
+
+int GetStarSprite(int star) {
+ return stars[star].sprite;
+}
+
+void SetStarSpriteRange(int start, int end, int slot) {
+ int sfix = start;
+ int efix = end;
+ if (start > Starfield.maxstars) sfix = Starfield.maxstars - 1;
+ if (end > Starfield.maxstars) efix = Starfield.maxstars;
+ for (int i = sfix; i < efix; i++)
+ stars[i].sprite = slot;
+}
+
+void DrawStars(int slot, int maskslot) {
+ int32 sw, sh = 0;
+ BITMAP *canvas = engine->GetSpriteGraphic(slot);
+ if (!canvas) engine->AbortGame("DrawStars: Can't load sprite slot.");
+ BITMAP *maskcanvas = engine->GetSpriteGraphic(maskslot);
+ if (!maskcanvas) engine->AbortGame("DrawStars: Can't load mask slot.");
+ engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
+ unsigned char **screenarray = engine->GetRawBitmapSurface(canvas);
+ unsigned char **maskarray = engine->GetRawBitmapSurface(maskcanvas);
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ //stars[i].z-= 0.5;
+ //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
+ float k = (float)Starfield.depthmultiplier / stars[i].z;
+ int px = static_cast<int>(stars[i].x * k + Starfield.originx);
+ int py = static_cast<int>(stars[i].y * k + Starfield.originy);
+ if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)MAX_DEPTH;
+ //stars[i].color = (rand () %240);
+ } else if (stars[i].z > 0) {
+ int ivalue = (63 - (int)stars[i].z);
+ if (ivalue > 63) ivalue = 63;
+ else if (ivalue < 0) ivalue = 0;
+ unsigned char value = (unsigned char)(ivalue);
+ unsigned char maskcolor = value << 2;
+ if (stars[i].sprite > 0) {
+ BITMAP *origspr = engine->GetSpriteGraphic(stars[i].sprite);
+ int scale = (ivalue + 1) * 100 >> 6;
+ //int scale = 50;
+ if (scale < 1) scale = 1;
+ /*
+ if (scale != 100)
+ {
+ unsigned char** orig = engine->GetRawBitmapSurface (origspr);
+ int32 h1,h2,w1,w2=0;
+ double fw2,fh2;
+ engine->GetBitmapDimensions (origspr,&w1,&h1,NULL);
+ fh2 = h1 * (scale / 100.0);
+ fw2 = w1 * (scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ if (w2 < 1) w2 = 1;
+ if (h2 < 1) h2 = 1;
+ resizspr = engine->CreateBlankBitmap (w2,h2,8);
+ unsigned char** resized = engine->GetRawBitmapSurface (resizspr);
+ int x_ratio = (int)((w1<<16)/w2) +1;
+ int y_ratio = (int)((h1<<16)/h2) +1;
+ int x2, y2 ;
+ for (int i=0;i<h2;i++)
+ {
+ for (int j=0;j<w2;j++)
+ {
+ x2 = ((j*x_ratio)>>16) ;
+ y2 = ((i*y_ratio)>>16) ;
+ resized [i][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface (resizspr);
+ }
+ //resizspr = origspr;
+ int32 w,h=0;
+ engine->GetBitmapDimensions (resizspr,&w,&h,NULL);
+ unsigned char **imagemap = engine->GetRawBitmapSurface (resizspr);
+ int ox = px - (w>>1);
+ int oy = py - (h>>1);
+ for (int dy=0;dy<h;dy++)
+ {
+ for (int dx=0;dx<w;dx++)
+ {
+ int ex = ox+dx;
+ int ey = oy+dy;
+ if (ex < sw && ex >= 0 && ey < sh && ey >= 0)
+ {
+ if (maskcolor > maskarray [ey][ex] && imagemap[dy][dx] > 0)
+ {
+ maskarray [ey][ex] = maskcolor;
+ screenarray [ey][ex] = imagemap[dy][dx];
+ }
+ }
+ }
+ }
+ */
+
+ unsigned char **orig = engine->GetRawBitmapSurface(origspr);
+ int32 h1, h2, w1, w2 = 0;
+ double fw2, fh2;
+ engine->GetBitmapDimensions(origspr, &w1, &h1, nullptr);
+ fh2 = h1 * (scale / 100.0);
+ fw2 = w1 * (scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ if (w2 < 1) w2 = 1;
+ if (h2 < 1) h2 = 1;
+ int x_ratio = (int)((w1 << 16) / w2) + 1;
+ int y_ratio = (int)((h1 << 16) / h2) + 1;
+ int x2, y2 ;
+ int ox = px - (w2 >> 1);
+ int oy = py - (h2 >> 1);
+ for (int ii = 0; ii < h2; ii++) {
+ int temprzy = ii * y_ratio;
+ int ey = oy + ii;
+ for (int j = 0; j < w2; j++) {
+ x2 = ((j * x_ratio) >> 16);
+ y2 = ((temprzy) >> 16);
+ int ex = ox + j;
+ if (ex < sw && ex >= 0 && ey < sh && ey >= 0) {
+ if (maskcolor > maskarray [ey][ex] && orig[y2][x2] > 0) {
+ maskarray [ey][ex] = maskcolor;
+ screenarray [ey][ex] = orig[y2][x2];
+ }
+ }
+ //resized [ii][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface(origspr);
+ } else if (stars[i].sprite == 0) {
+ if (stars[i].maxrad == 1) {
+ if (px < sw && px >= 0 && py < sh && py >= 0) {
+ if (maskcolor > maskarray[py][px]) {
+ maskarray[py][px] = maskcolor;
+ screenarray[py][px] = stars[i].color;
+ }
+ }
+ } else {
+ int scale = ((((int)stars[i].z) * 100) / 63);
+ if (scale < 1) scale = 1;
+ int radius = (stars[i].maxrad * (100 - scale) / 100);
+ int radsq = radius * radius;
+ //unsigned char color = GetColor565 (value>>1,value,value>>1);
+ unsigned char color = stars[i].color;
+ for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
+ int cysq = cy * cy;
+ for (int cx = -radius; cx <= radius; cx++) {
+ int cxsq = cx * cx;
+ int dx = cx + px;
+ int dy = cy + py;
+ if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) {
+ if (maskcolor > maskarray [dy][dx]) {
+ maskarray [dy][dx] = maskcolor;
+ screenarray [dy][dx] = color;
+ }
+ }
+ }
+ }
+ /*
+ for(int cy=-radius; cy<=radius; cy++) //Draw a circle around the point, for the color.
+ {
+ int cysq = cy*cy;
+ for(int cx=-radius; cx<=radius; cx++)
+ {
+ int cxsq = cx*cx;
+ int dx = cx+px;
+ int dy = cy+py;
+ if((cxsq+cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0)
+ {
+ if (maskarray [dy][dx] == maskcolor)screenarray [dy][dx] = color;
+ }
+ }
+ }
+ */
+ }
+ }
+ }
+ }
+ engine->ReleaseBitmapSurface(canvas);
+ engine->ReleaseBitmapSurface(maskcanvas);
+ engine->NotifySpriteUpdated(slot);
+ engine->NotifySpriteUpdated(maskslot);
+}
+
+
+int CreateTranslucentOverlay(int id, int spriteId, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) {
+ BITMAP *testspr = engine->GetSpriteGraphic(spriteId);
+ if (testspr) overlay[id].sprite = spriteId;
+ else engine->AbortGame("CreateTranslucentOverlay: Invalid spriteId.");
+ engine->ReleaseBitmapSurface(testspr);
+ overlay[id].level = MAX(0, MIN(level, 4));
+ overlay[id].trans = MAX(0, MIN(alpha, 255));
+ overlay[id].spritemask = mask;
+ overlay[id].x = ox;
+ overlay[id].y = oy;
+ overlay[id].enabled = true;
+ overlay[id].blendtype = blendmode;
+ return 0;
+}
+
+int DeleteTranslucentOverlay(int id) {
+ overlay[id].enabled = false;
+ overlay[id].sprite = 0;
+ overlay[id].x = 0;
+ overlay[id].y = 0;
+ overlay[id].level = 0;
+ overlay[id].trans = 0;
+ return 0;
+}
+
+int MoveTranslucentOverlay(int id, int ox, int oy) {
+ overlay[id].x = ox;
+ overlay[id].y = oy;
+ return 0;
+}
+
+int GetTranslucentOverlayX(int id) {
+ return overlay[id].x;
+}
+
+int GetTranslucentOverlayY(int id) {
+ return overlay[id].y;
+}
+
+int GetTranslucentOverlaySprite(int id) {
+ return overlay[id].sprite;
+}
+
+int GetTranslucentOverlayLevel(int id) {
+ return overlay[id].level;
+}
+
+int GetTranslucentOverlayEnabled(int id) {
+ return overlay[id].enabled;
+}
+
+int GetTranslucentOverlayAlpha(int id) {
+ return overlay[id].trans;
+}
+
+int SetTranslucentOverlayAlpha(int id, int alpha) {
+ if (alpha >= 0 && alpha < 256)
+ overlay[id].trans = alpha;
+ else
+ engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected.");
+ return 0;
+}
+
+int SetTranslucentOverlayEnabled(int id, int toggle) {
+ if (toggle > 0)
+ overlay[id].enabled = true;
+ else
+ overlay[id].enabled = false;
+ return 0;
+}
+
+void SetCharacterReflected(int id, int refl) {
+ if (refl > 0) Reflection.Characters[id].reflect = 1;
+ else Reflection.Characters[id].reflect = 0;
+}
+
+void SetObjectReflected(int id, int refl) {
+ if (refl > 0)
+ Reflection.Objects[id].reflect = 1;
+ else
+ Reflection.Objects[id].reflect = 0;
+}
+
+int GetCharacterReflected(int id) {
+ return Reflection.Characters[id].reflect;
+}
+
+int GetObjectReflected(int id) {
+ return Reflection.Objects[id].reflect;
+}
+
+void ReplaceCharacterReflectionView(int id, int view) {
+ Reflection.Characters[id].replaceview = view - 1;
+}
+
+void SetObjectReflectionIgnoreScaling(int id, int wb) {
+ if (wb) Reflection.Objects[id].ignorescaling = 1;
+ else Reflection.Objects[id].ignorescaling = 0;
+}
+
+int DrawReflections(int id, int charobj = 0) {
+ int32 screenw, screenh;
+ int32 bgw, bgh;
+ engine->GetScreenDimensions(&screenw, &screenh, nullptr);
+ BITMAP *bgmask = engine->GetBackgroundScene(1);
+ if (bgmask == nullptr) return 1;
+ //BITMAP *virtsc = engine->GetVirtualScreen();
+ BITMAP *walkbehind = engine->GetRoomMask(MASK_WALKBEHIND);
+ //if (!virtsc) engine->AbortGame ("Can't load virtual screen.");
+ if (!walkbehind) engine->AbortGame("DrawRelfections: Can't load Walkbehind into memory.");
+ engine->GetBitmapDimensions(walkbehind, &bgw, &bgh, nullptr);
+ if (!bgmask) engine->AbortGame("DrawReflections: Can't load reflection mask.");
+ //unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc);
+ unsigned char **wbarray = engine->GetRawBitmapSurface(walkbehind);
+ unsigned char **maskarray = engine->GetRawBitmapSurface(bgmask);
+ //Initialize stuff
+ BITMAP *charsprite = nullptr;
+ BITMAP *charsprite2 = nullptr;
+ AGSCharacter *currchar = nullptr;
+ AGSObject *currobj;
+ int cox = 0, coy = 0, coz = 0;
+ int scale = 0;
+ //Get character, and their sprite.
+ if (charobj == 0) {
+ currchar = engine->GetCharacter(id);
+ /*int view = 0;
+ if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1;
+ else view = Reflection.Characters[id].replaceview;
+ */
+ AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame);
+ charsprite = engine->GetSpriteGraphic(vf->pic);
+ long scaling = currchar->flags & CHF_NOSCALING;
+ if (!scaling)scale = engine->GetAreaScaling(currchar->x, currchar->y);
+ else scale = 100;
+ cox = currchar->x;
+ coy = currchar->y;
+ coz = currchar->z;
+ } else if (charobj == 1) {
+ currobj = engine->GetObject(id);
+
+ charsprite = engine->GetSpriteGraphic(currobj->num);
+ if (Reflection.Objects[id].ignorescaling) scale = 100;
+ else scale = engine->GetAreaScaling(currobj->x, currobj->y);
+ cox = currobj->x;
+ if (currobj->baseline < 0) coy = currobj->y;
+ else coy = currobj->baseline;
+ coz = 0;
+ }
+ bool scaled = false;
+ int32 w, h;
+ engine->GetBitmapDimensions(charsprite, &w, &h, nullptr);
+ if (scale != 100) {
+ unsigned char **orig = engine->GetRawBitmapSurface(charsprite);
+ int h1, h2, w1, w2;
+ double fw2, fh2;
+ h1 = h;
+ w1 = w;
+ fh2 = h1 * ((double)scale / 100.0);
+ fw2 = w1 * ((double)scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ charsprite2 = engine->CreateBlankBitmap(w2, h2, 8);
+ unsigned char **resized = engine->GetRawBitmapSurface(charsprite2);
+ int x_ratio = (int)((w1 << 16) / w2) + 1;
+ int y_ratio = (int)((h1 << 16) / h2) + 1;
+ int x2, y2 ;
+ for (int i = 0; i < h2; i++) {
+ for (int j = 0; j < w2; j++) {
+ x2 = ((j * x_ratio) >> 16) ;
+ y2 = ((i * y_ratio) >> 16) ;
+ resized [i][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface(charsprite2);
+ scaled = true;
+ w = w2;
+ h = h2;
+ } else {
+ charsprite2 = charsprite;
+ }
+ int transamount = 0;
+ unsigned char **spritearray = engine->GetRawBitmapSurface(charsprite2);
+ unsigned char **charbuffer = engine->GetRawBitmapSurface(rcolormap);
+ unsigned char **alphaarray = engine->GetRawBitmapSurface(ralphamap);
+ int i = h - 1, j = 0;
+ int32 ox = cox;
+ if (charobj == 0) ox = ox - (w / 2);
+ int32 oy = coy + coz - 1;
+ engine->RoomToViewport(&ox, &oy);
+ int yoffset = 0;
+ int translevel = 7;
+ //bool dither = false;
+ //bool dodither = false;
+ int counter = 0;
+ int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0));
+ int delay = screenh / rowcount;
+ int *obst;
+ int flipped = 0;
+ if (charobj == 0) {
+ int (*sfGetGameParameter)(int, int, int, int);
+ sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
+ flipped = sfGetGameParameter(13, currchar->view + 1, currchar->loop, currchar->frame);
+ } else flipped = 0;
+ obst = new int [w];
+ for (int k = 0; k < w; k++) {
+ obst[k] = 0;
+ }
+ while (i > 0) {
+ //if ((counter == delay/2-1 || counter == delay-1) && yoffset < 36) dodither = (!dodither);
+ if (counter == delay) {
+ counter = 0;
+ if (translevel > 0) translevel--;
+ } else counter++;
+ yoffset++;
+ while (j < w) {
+ int xoffset;
+ if (flipped == 1) xoffset = w - j - 1;
+ else xoffset = j;
+ int32 rx = ox + xoffset, ry = oy + yoffset;
+ int wbb = 0;
+ engine->ViewportToRoom(&rx, &ry);
+ if (ry > 0 && ry < bgh && rx > 0 && rx < bgw) {
+ if (wbarray [ry][rx] > 0) {
+ wbb = engine->GetWalkbehindBaseline(wbarray[ry][rx]);
+ }
+ if (maskarray[ry][rx] == 21) obst[j] = 1;
+ }
+
+ //dither = (!dither);
+ transamount = 32 * translevel;
+ if (spritearray [i][j] != 0 && oy + yoffset < screenh && ox + xoffset < screenw && oy + yoffset >= 0 && ox + xoffset >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg.
+ if (wbb < ry && obst[j] == 0 && (oy > reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))])) {
+ //charbuffer[oy+yoffset][ox+xoffset] = MixColorAlpha (spritearray [i][j],charbuffer[oy+yoffset][ox+xoffset],transamount);
+ charbuffer [oy + yoffset][ox + xoffset] = spritearray [i][j];
+ alphaarray [oy + yoffset][ox + xoffset] = transamount;
+ reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))] = oy;
+ }
+ }
+ j++;
+ }
+ //if (w % 2 == 0) dither = (!dither);
+ i--;
+ j = 0;
+ }
+
+ delete [] obst;
+ if (scaled == true)engine->FreeBitmap(charsprite2);
+ engine->ReleaseBitmapSurface(charsprite);
+ //engine->ReleaseBitmapSurface (virtsc);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(bgmask);
+ engine->ReleaseBitmapSurface(walkbehind);
+ engine->ReleaseBitmapSurface(rcolormap);
+ engine->ReleaseBitmapSurface(ralphamap);
+ engine->MarkRegionDirty(ox, oy, ox + w, oy + h);
+ return 0;
+}
+
+
+int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) {
+ BITMAP *maskspr = nullptr;
+ unsigned char **maskarray = nullptr;
+ if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
+ if (!maskspr && mask > 0) {
+ char maskerr [100];
+ snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
+ engine->AbortGame(maskerr);
+ }
+ // Get a reference to the screen we'll draw onto
+ BITMAP *bgspr = engine->GetSpriteGraphic(bg);
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
+ if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background");
+ //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
+ if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay spriteId into memory.");
+ // Get its surface
+ int32 sprw, sprh, coldepth;
+ int32 bgw, bgh;
+ engine->GetBitmapDimensions(bgspr, &bgw, &bgh, &coldepth);
+ engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
+
+ unsigned char **bgarray = engine->GetRawBitmapSurface(bgspr);
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
+ if (mask > 0) maskarray = engine->GetRawBitmapSurface(maskspr);
+ int tloffset = 255 - translevel;
+ int x = 0;
+ int y = 0;
+ //int transamount = 256 * translevel; //old
+ while (y < sprh) {
+ while (x < sprw) {
+ if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the bg.
+ if (mask > 0) {
+ translevel = MAX(maskarray [y][x] - tloffset, 0);
+ }
+ //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
+ if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
+ else if (blendmode == 1) spritearray[y][x] = Mix::MixColorAdditive(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
+ }
+ x++;
+ }
+ x = 0;
+ y++;
+ }
+
+ // Release the screen so that the engine can continue
+ engine->ReleaseBitmapSurface(bgspr);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(spritespr);
+ engine->NotifySpriteUpdated(spriteId);
+ return 0;
+}
+
+int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) {
+ if (translevel == 0) return 0;
+ BITMAP *maskspr = nullptr;
+ unsigned char **maskarray = nullptr;
+ // Get a reference to the screen we'll draw onto
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
+ if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
+ if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen.");
+ //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
+ if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay spriteId into memory.");
+ // Get its surface
+ int32 sprw, sprh, coldepth;
+ int32 screenw, screenh;
+ engine->GetScreenDimensions(&screenw, &screenh, &coldepth);
+ engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
+ unsigned char **charbuffer = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
+ if (mask > 0) {
+ if (!maskspr && mask > 0) {
+ char maskerr [100];
+ snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
+ engine->AbortGame(maskerr);
+ }
+ maskarray = engine->GetRawBitmapSurface(maskspr);
+ }
+ int tloffset = 255 - translevel;
+ int x = 0;
+ int y = 0;
+ //int transamount = 256 * translevel; //old
+ while (y < sprh) {
+ while (x < sprw) {
+ if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the screen.
+ //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
+ if (mask > 0) {
+ translevel = MAX(maskarray [y][x] - tloffset, 0);
+ }
+ if (blendmode == 0) {
+ if (translevel == 255) {
+ charbuffer[y + oy][x + ox] = spritearray [y][x];
+ } else charbuffer[y + oy][x + ox] = Mix::MixColorAlpha(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
+ } else if (blendmode == 1) charbuffer[y + oy][x + ox] = Mix::MixColorAdditive(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
+ }
+ x++;
+ }
+ x = 0;
+ y++;
+ }
+
+ // Release the screen so that the engine can continue
+ long dirtywidth = ox + sprw;
+ if (dirtywidth > screenw) dirtywidth = screenw - 1;
+ long dirtyheight = oy + sprh;
+ if (dirtyheight > screenh) dirtywidth = screenh - 1;
+ engine->ReleaseBitmapSurface(virtsc);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(spritespr);
+ if (mask > 0) engine->ReleaseBitmapSurface(maskspr);
+ engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+
+AGSPalRender::AGSPalRender() : DLL() {
+ DLL_METHOD(AGS_GetPluginName);
+ DLL_METHOD(AGS_EngineStartup);
+ DLL_METHOD(AGS_EngineShutdown);
+ DLL_METHOD(AGS_EngineOnEvent);
+}
+
+const char *AGSPalRender::AGS_GetPluginName() {
+ return "PALgorithms Translucent Overlay Renderer";
+}
+
+void AGSPalRender::AGS_EngineStartup(IAGSEngine *lpEngine) {
+ engine = lpEngine;
+
+ // Make sure it's got the version with the features we need
+ if (engine->version < 3) {
+ engine->AbortGame("Engine interface is too old, need newer version of AGS.");
+ }
+ engine->RegisterScriptFunction("PALInternal::LoadCLUT^1", (void *)LoadCLUT);
+ engine->RegisterScriptFunction("PALInternal::CycleRemap^2", (void *)CycleRemap);
+ engine->RegisterScriptFunction("PALInternal::GetColor565^3", (void *)GetColor565);
+ engine->RegisterScriptFunction("PALInternal::GetLuminosityFromPalette^1", (void *)GetLuminosityFromPalette);
+ engine->RegisterScriptFunction("PALInternal::FastSin^1", (void *)AGSFastSin);
+ engine->RegisterScriptFunction("PALInternal::FastCos^1", (void *)AGSFastCos);
+ engine->RegisterScriptFunction("PALInternal::FastRoot^1", (void *)root);
+ engine->RegisterScriptFunction("PALInternal::GetRemappedSlot^1", (void *)GetRemappedSlot);
+ engine->RegisterScriptFunction("PALInternal::ResetRemapping^0", (void *)ResetRemapping);
+ engine->RegisterScriptFunction("PALInternal::GetModifiedBackgroundImage", (void *)GetModifiedBackgroundImage);
+ engine->RegisterScriptFunction("PALInternal::WriteObjectivePalette^4", (void *)WriteObjectivePalette);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteR^1", (void *)ReadObjectivePaletteR);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteB^1", (void *)ReadObjectivePaletteB);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteG^1", (void *)ReadObjectivePaletteG);
+
+ engine->RegisterScriptFunction("Raycast::Render^1", (void *)Raycast_Render);
+ engine->RegisterScriptFunction("Raycast::LoadMap^4", (void *)LoadMap);
+ engine->RegisterScriptFunction("Raycast::Initialize", (void *)Init_Raycaster);
+ engine->RegisterScriptFunction("Raycast::MakeTextures^1", (void *)MakeTextures);
+ engine->RegisterScriptFunction("Raycast::MoveForward^0", (void *)MoveForward);
+ engine->RegisterScriptFunction("Raycast::MoveBackward^0", (void *)MoveBackward);
+ engine->RegisterScriptFunction("Raycast::RotateLeft^0", (void *)RotateLeft);
+ engine->RegisterScriptFunction("Raycast::RotateRight^0", (void *)RotateRight);
+ engine->RegisterScriptFunction("Raycast::SetCameraPosition^2", (void *)Ray_SetPlayerPosition);
+ engine->RegisterScriptFunction("Raycast::GetCameraX^0", (void *)Ray_GetPlayerX);
+ engine->RegisterScriptFunction("Raycast::GetCameraY^0", (void *)Ray_GetPlayerY);
+ engine->RegisterScriptFunction("Raycast::GetCameraAngle^0", (void *)Ray_GetPlayerAngle);
+ engine->RegisterScriptFunction("Raycast::SetCameraAngle^1", (void *)Ray_SetPlayerAngle);
+ engine->RegisterScriptFunction("Raycast::InitSprite^9", (void *)Ray_InitSprite);
+ engine->RegisterScriptFunction("Raycast::UnloadEngine^0", (void *)QuitCleanup);
+ engine->RegisterScriptFunction("Raycast::GetHotspotAtXY^2", (void *)Ray_GetHotspotAt);
+ engine->RegisterScriptFunction("Raycast::GetObjectAtXY^2", (void *)Ray_GetObjectAt);
+ engine->RegisterScriptFunction("Raycast::SetSpriteInteractObj^2", (void *)Ray_SetSpriteInteractObj);
+ engine->RegisterScriptFunction("Raycast::GetSpriteInteractObj^1", (void *)Ray_GetSpriteInteractObj);
+ engine->RegisterScriptFunction("Raycast::SetSpritePosition^3", (void *)Ray_SetSpritePosition);
+ engine->RegisterScriptFunction("Raycast::SetSpriteVertOffset^2", (void *)Ray_SetSpriteVertOffset);
+ engine->RegisterScriptFunction("Raycast::GetSpriteVertOffset^1", (void *)Ray_GetSpriteVertOffset);
+ engine->RegisterScriptFunction("Raycast::GetSpriteX^1", (void *)Ray_GetSpriteX);
+ engine->RegisterScriptFunction("Raycast::GetSpriteY^1", (void *)Ray_GetSpriteY);
+ engine->RegisterScriptFunction("Raycast::SetWallHotspot^2", (void *)Ray_SetWallHotspot);
+ engine->RegisterScriptFunction("Raycast::SetWallTextures^5", (void *)Ray_SetWallTextures);
+ engine->RegisterScriptFunction("Raycast::SetWallSolid^5", (void *)Ray_SetWallSolid);
+ engine->RegisterScriptFunction("Raycast::SetWallIgnoreLighting^5", (void *)Ray_SetWallIgnoreLighting);
+ engine->RegisterScriptFunction("Raycast::SetWallAlpha^5", (void *)Ray_SetWallAlpha);
+ engine->RegisterScriptFunction("Raycast::SetWallBlendType^5", (void *)Ray_SetWallBlendType);
+ engine->RegisterScriptFunction("Raycast::GetMoveSpeed^0", (void *)Ray_GetMoveSpeed);
+ engine->RegisterScriptFunction("Raycast::SetMoveSpeed^1", (void *)Ray_SetMoveSpeed);
+ engine->RegisterScriptFunction("Raycast::GetRotSpeed^0", (void *)Ray_GetRotSpeed);
+ engine->RegisterScriptFunction("Raycast::SetRotSpeed^1", (void *)Ray_SetRotSpeed);
+ engine->RegisterScriptFunction("Raycast::GetWallAt^2", (void *)Ray_GetWallAt);
+ engine->RegisterScriptFunction("Raycast::GetLightAt^2", (void *)Ray_GetLightAt);
+ engine->RegisterScriptFunction("Raycast::SetLightAt^3", (void *)Ray_SetLightAt);
+ engine->RegisterScriptFunction("Raycast::SetWallAt^3", (void *)Ray_SetWallAt);
+ engine->RegisterScriptFunction("Raycast::SetPlaneY^1", (void *)Ray_SetPlaneY);
+ engine->RegisterScriptFunction("Raycast::GetDistanceAt^2", (void *)Ray_GetDistanceAt);
+ engine->RegisterScriptFunction("Raycast::GetSpriteAngle^1", (void *)Ray_GetSpriteAngle);
+ engine->RegisterScriptFunction("Raycast::SetSpriteAngle^2", (void *)Ray_SetSpriteAngle);
+ engine->RegisterScriptFunction("Raycast::SetSpriteView^2", (void *)Ray_SetSpriteView);
+ engine->RegisterScriptFunction("Raycast::GetSpriteView^1", (void *)Ray_GetSpriteView);
+ engine->RegisterScriptFunction("Raycast::SetSpriteFrame^2", (void *)Ray_SetSpriteFrame);
+ engine->RegisterScriptFunction("Raycast::GetSpriteFrame^1", (void *)Ray_GetSpriteFrame);
+ engine->RegisterScriptFunction("Raycast::SetSpritePic^2", (void *)Ray_SetSpritePic);
+ engine->RegisterScriptFunction("Raycast::GetSpritePic^1", (void *)Ray_GetSpritePic);
+ engine->RegisterScriptFunction("Raycast::SetSkyBox^1", (void *)Ray_SetSkyBox);
+ engine->RegisterScriptFunction("Raycast::SetSpriteAlpha^2", (void *)Ray_SetSpriteAlpha);
+ engine->RegisterScriptFunction("Raycast::GetSpriteAlpha^1", (void *)Ray_GetSpriteAlpha);
+ engine->RegisterScriptFunction("Raycast::GetSkyBox^1", (void *)Ray_GetSkyBox);
+ engine->RegisterScriptFunction("Raycast::SetAmbientLight^1", (void *)Ray_SetAmbientLight);
+ engine->RegisterScriptFunction("Raycast::SetAmbientColor^2", (void *)Ray_SetAmbientColor);
+ engine->RegisterScriptFunction("Raycast::GetAmbientLight^0", (void *)Ray_GetAmbientLight);
+ engine->RegisterScriptFunction("Raycast::GetAmbientWeight^0", (void *)Ray_GetAmbientWeight);
+ engine->RegisterScriptFunction("Raycast::GetTileX_At^2", (void *)Ray_GetTileX_At);
+ engine->RegisterScriptFunction("Raycast::GetTileY_At^2", (void *)Ray_GetTileY_At);
+ engine->RegisterScriptFunction("Raycast::DrawTile^2", (void *)Ray_DrawTile);
+ engine->RegisterScriptFunction("Raycast::DrawOntoTile^2", (void *)Ray_DrawOntoTile);
+ engine->RegisterScriptFunction("Raycast::SetNoClip^1", (void *)Ray_SetNoClip);
+ engine->RegisterScriptFunction("Raycast::GetNoClip^0", (void *)Ray_GetNoClip);
+ engine->RegisterScriptFunction("Raycast::GetSpriteScaleX^1", (void *)Ray_GetSpriteScaleX);
+ engine->RegisterScriptFunction("Raycast::SetSpriteScaleX^2", (void *)Ray_SetSpriteScaleX);
+ engine->RegisterScriptFunction("Raycast::GetSpriteScaleY^1", (void *)Ray_GetSpriteScaleY);
+ engine->RegisterScriptFunction("Raycast::SetSpriteScaleY^2", (void *)Ray_SetSpriteScaleY);
+ engine->RegisterScriptFunction("Raycast::GetSpriteBlendType^1", (void *)Ray_GetSpriteBlendType);
+ engine->RegisterScriptFunction("Raycast::SetSpriteBlendType^2", (void *)Ray_SetSpriteBlendType);
+
+
+ engine->RegisterScriptFunction("Raycast::SetFloorAt^3", (void *)Ray_SetFloorAt);
+ engine->RegisterScriptFunction("Raycast::SetCeilingAt^3", (void *)Ray_SetCeilingAt);
+ engine->RegisterScriptFunction("Raycast::GetCeilingAt^2", (void *)Ray_GetCeilingAt);
+ engine->RegisterScriptFunction("Raycast::GetFloorAt^2", (void *)Ray_GetFloorAt);
+ engine->RegisterScriptFunction("Raycast::GetLightingAt^2", (void *)Ray_GetLightingAt);
+ engine->RegisterScriptFunction("Raycast::SetLightingAt^3", (void *)Ray_SetLightingAt);
+ engine->RegisterScriptFunction("Raycast::GetWallHotspot^1", (void *)Ray_GetWallHotspot);
+ engine->RegisterScriptFunction("Raycast::GetWallTexture^2", (void *)Ray_GetWallTexture);
+ engine->RegisterScriptFunction("Raycast::GetWallSolid^2", (void *)Ray_GetWallSolid);
+ engine->RegisterScriptFunction("Raycast::GetWallIgnoreLighting^2", (void *)Ray_GetWallIgnoreLighting);
+ engine->RegisterScriptFunction("Raycast::GetWallAlpha^2", (void *)Ray_GetWallAlpha);
+ engine->RegisterScriptFunction("Raycast::GetWallBlendType^2", (void *)Ray_GetWallBlendType);
+ engine->RegisterScriptFunction("Raycast::SelectTile^3", (void *)Ray_SelectTile);
+ engine->RegisterScriptFunction("Raycast::HasSeenTile^2", (void *)Ray_HasSeenTile);
+
+ engine->RegisterScriptFunction("LensDistort::SetPos^2", (void *)SetLensPos);
+ engine->RegisterScriptFunction("LensDistort::GetX^0", (void *)GetLensX);
+ engine->RegisterScriptFunction("LensDistort::GetY^0", (void *)GetLensY);
+ engine->RegisterScriptFunction("LensDistort::Set^1", (void *)SetLensDrawn);
+ engine->RegisterScriptFunction("LensDistort::IsDrawn^0", (void *)GetLensDrawn);
+ engine->RegisterScriptFunction("LensDistort::SetOffsetClamp^1", (void *)SetLensOffsetClamp);
+ engine->RegisterScriptFunction("LensDistort::GetOffsetClamp^0", (void *)GetLensOffsetClamp);
+ engine->RegisterScriptFunction("LensDistort::GetLevel^0", (void *)GetLensLevel);
+ engine->RegisterScriptFunction("LensDistort::SetLevel^1", (void *)GetLensLevel);
+ engine->RegisterScriptFunction("LensDistort::Initialize^6", (void *)LensInitialize);
+
+ engine->RegisterScriptFunction("Translucence::CreateOverlay^8", (void *)CreateTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::DeleteOverlay^1", (void *)DeleteTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::Move^3", (void *)MoveTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::GetOverlayX^1", (void *)GetTranslucentOverlayX);
+ engine->RegisterScriptFunction("Translucence::GetOverlayY^1", (void *)GetTranslucentOverlayY);
+ engine->RegisterScriptFunction("Translucence::GetOverlaySprite^1", (void *)GetTranslucentOverlaySprite);
+ engine->RegisterScriptFunction("Translucence::GetOverlayLevel^1", (void *)GetTranslucentOverlayLevel);
+ engine->RegisterScriptFunction("Translucence::GetOverlayEnabled^1", (void *)GetTranslucentOverlayEnabled);
+ engine->RegisterScriptFunction("Translucence::GetOverlayAlpha^1", (void *)GetTranslucentOverlayAlpha);
+ engine->RegisterScriptFunction("Translucence::SetOverlayAlpha^2", (void *)SetTranslucentOverlayAlpha);
+ engine->RegisterScriptFunction("Translucence::SetOverlayEnabled^2", (void *)SetTranslucentOverlayEnabled);
+ engine->RegisterScriptFunction("Translucence::DrawTransSprite^6", (void *)DrawTransSprite);
+
+ engine->RegisterScriptFunction("Starfield::GetOverscan^0", (void *)GetStarfieldOverscan);
+ engine->RegisterScriptFunction("Starfield::SetOverscan^1", (void *)SetStarfieldOverscan);
+ engine->RegisterScriptFunction("Starfield::GetOriginX^0", (void *)GetStarfieldOriginX);
+ engine->RegisterScriptFunction("Starfield::GetOriginY^0", (void *)GetStarfieldOriginY);
+ engine->RegisterScriptFunction("Starfield::SetDepthMultiplier^1", (void *)SetStarfieldDepthMultiplier);
+ engine->RegisterScriptFunction("Starfield::GetDepthMultiplier^0", (void *)GetStarfieldDepthMultiplier);
+ engine->RegisterScriptFunction("Starfield::GetMaxStars^0", (void *)GetStarfieldMaxStars);
+ engine->RegisterScriptFunction("Starfield::SetStarSpriteScaleBoost^1", (void *)SetStarSpriteScaleBoost);
+ engine->RegisterScriptFunction("Starfield::GetStarSpriteScaleBoost^0", (void *)GetStarSpriteScaleBoost);
+ engine->RegisterScriptFunction("Starfield::SetStarMaxRadius^2", (void *)SetStarMaxRadius);
+ engine->RegisterScriptFunction("Starfield::GetStarMaxRadius^0", (void *)GetStarMaxRadius);
+ engine->RegisterScriptFunction("Starfield::GetStarX^1", (void *)GetStarX);
+ engine->RegisterScriptFunction("Starfield::GetStarY^1", (void *)GetStarY);
+ engine->RegisterScriptFunction("Starfield::GetStarZ^1", (void *)GetStarZ);
+ engine->RegisterScriptFunction("Starfield::SetStarPosition^4", (void *)SetStarPosition);
+ engine->RegisterScriptFunction("Starfield::RotateStar^4", (void *)RotateStar);
+ engine->RegisterScriptFunction("Starfield::SetStarColor^2", (void *)SetStarColor);
+ engine->RegisterScriptFunction("Starfield::GetStarColor^1", (void *)GetStarColor);
+ engine->RegisterScriptFunction("Starfield::SetStarSprite^2", (void *)SetStarSprite);
+ engine->RegisterScriptFunction("Starfield::GetStarSprite^1", (void *)GetStarSprite);
+ engine->RegisterScriptFunction("Starfield::SetStarSpriteRange^3", (void *)SetStarSpriteRange);
+ engine->RegisterScriptFunction("Starfield::Initialize^2", (void *)InitializeStars);
+ engine->RegisterScriptFunction("Starfield::Iterate^1", (void *)IterateStars);
+ engine->RegisterScriptFunction("Starfield::Draw^2", (void *)DrawStars);
+ engine->RegisterScriptFunction("Starfield::SetOriginPoint^2", (void *)SetStarsOriginPoint);
+
+ engine->RegisterScriptFunction("Plasma::DoFire^8", (void *)DoFire);
+ engine->RegisterScriptFunction("Plasma::SetPlasmaType^5", (void *)SetPlasmaType);
+ engine->RegisterScriptFunction("Plasma::ResetPlasmaSettings^0", (void *)ResetPlasmaSettings);
+ engine->RegisterScriptFunction("Plasma::DrawPlasma^3", (void *)DrawPlasma);
+ engine->RegisterScriptFunction("Plasma::SetRootType^1", (void *)SetPlasmaRootType);
+ engine->RegisterScriptFunction("Plasma::GetRootType^0", (void *)GetPlasmaRootType);
+
+ engine->RegisterScriptFunction("Reflections::Set^1", (void *)SetReflections);
+ engine->RegisterScriptFunction("Reflections::IsReflecting^0", (void *)IsReflectionsOn);
+ engine->RegisterScriptFunction("Reflections::SetCharacterReflected^2", (void *)SetCharacterReflected);
+ engine->RegisterScriptFunction("Reflections::GetCharacterReflected^1", (void *)GetCharacterReflected);
+ engine->RegisterScriptFunction("Reflections::SetObjectReflected^2", (void *)SetObjectReflected);
+ engine->RegisterScriptFunction("Reflections::GetObjectReflected^1", (void *)GetObjectReflected);
+ engine->RegisterScriptFunction("Reflections::ReplaceCharacterReflectionView^2", (void *)ReplaceCharacterReflectionView);
+ engine->RegisterScriptFunction("Reflections::SetObjectReflectionIgnoreScaling^2", (void *)SetObjectReflectionIgnoreScaling);
+ engine->RequestEventHook(AGSE_PRESCREENDRAW);
+ engine->RequestEventHook(AGSE_PREGUIDRAW);
+ engine->RequestEventHook(AGSE_POSTSCREENDRAW);
+ engine->RequestEventHook(AGSE_SAVEGAME);
+ engine->RequestEventHook(AGSE_RESTOREGAME);
+ engine->RequestEventHook(AGSE_ENTERROOM);
+ stars = new starstype [MAX_STARS];
+ Starfield.maxstars = MAX_STARS;
+ Starfield.depthmultiplier = 256;
+ Starfield.speed = 0.5;
+ Starfield.originx = 160;
+ Starfield.originy = 100;
+ Reflection.Characters = new charrefopt [engine->GetNumCharacters()]();
+ lens = new LensDistort [LENS_WIDTH * LENS_WIDTH]();
+ //PreMultiply_Alphas ();
+ plasmaroottype = 0;
+ Make_Sin_Lut();
+ Init_Raycaster();
+}
+
+void AGSPalRender::AGS_EngineShutdown() {
+ // no work to do here - but if we had created any dynamic sprites,
+ // we should delete them here
+ delete[] Reflection.Characters;
+ delete[] Reflection.Objects;
+ //QuitCleanup();
+}
+
+NumberPtr AGSPalRender::AGS_EngineOnEvent(int event, NumberPtr data) {
+ if (event == AGSE_PRESCREENDRAW && clutslot > 0) {
+ if (drawreflections) {
+ int32 sh, sw = 0;
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ reflectionmap = new long[sw * sh]();
+ rcolormap = engine->CreateBlankBitmap(sw, sh, 8);
+ ralphamap = engine->CreateBlankBitmap(sw, sh, 8);
+ for (int i = 0; i < engine->GetNumCharacters(); i++) {
+ if (Reflection.Characters[i].reflect == 0) continue;
+ AGSCharacter *tempchar = engine->GetCharacter(i);
+ if (tempchar->room != engine->GetCurrentRoom()) continue; //if character isn't even in the room, go to next iteration.
+ int32 vx = tempchar->x;
+ int32 vy = tempchar->y;
+ engine->RoomToViewport(&vx, &vy);
+ AGSViewFrame *vf = engine->GetViewFrame(tempchar->view + 1, tempchar->loop, tempchar->frame);
+ int w = engine->GetSpriteWidth(vf->pic);
+ int h = engine->GetSpriteHeight(vf->pic);
+ vx = vx - (w / 2);
+ int32 vxmax = vx + w;
+ int32 vymax = vy + h;
+ if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
+ DrawReflections(i, 0);
+ }
+ for (int i = 0; i < engine->GetNumObjects(); i++) {
+ if (Reflection.Objects[i].reflect == 0) continue;
+ AGSObject *tempobj = engine->GetObject(i);
+ if (!tempobj->on) continue;
+ int32 vx = tempobj->x;
+ int32 vy = tempobj->baseline - tempobj->y;
+ engine->RoomToViewport(&vx, &vy);
+ int32 w = engine->GetSpriteWidth(tempobj->num);
+ int32 h = engine->GetSpriteHeight(tempobj->num);
+ int32 vxmax = vx + w;
+ int32 vymax = vy + h;
+ if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
+ DrawReflections(i, 1);
+ }
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ unsigned char **screenbuffer = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **colorbuffer = engine->GetRawBitmapSurface(rcolormap);
+ unsigned char **alphabuffer = engine->GetRawBitmapSurface(ralphamap);
+ for (int y = 0; y < sh; y++)
+ for (int x = 0; x < sw; x++)
+ screenbuffer[y][x] = Mix::MixColorAlpha(colorbuffer[y][x], screenbuffer[y][x], alphabuffer[y][x]);
+ engine->ReleaseBitmapSurface(rcolormap);
+ engine->ReleaseBitmapSurface(ralphamap);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->FreeBitmap(rcolormap);
+ engine->FreeBitmap(ralphamap);
+ delete [] reflectionmap;
+ }
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 0) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 0) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_PREGUIDRAW && clutslot > 0) {
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 1) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 2) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_POSTSCREENDRAW && clutslot > 0) {
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 3) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 2) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 4) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_SAVEGAME) {
+ for (int i = 0; i < MAX_OVERLAYS; ++i) {
+ engine->FWrite(&overlay[i].sprite, sizeof(int), data);
+ engine->FWrite(&overlay[i].spritemask, sizeof(int), data);
+ engine->FWrite(&overlay[i].x, sizeof(int), data);
+ engine->FWrite(&overlay[i].y, sizeof(int), data);
+ engine->FWrite(&overlay[i].level, sizeof(int), data);
+ engine->FWrite(&overlay[i].trans, sizeof(int), data);
+ engine->FWrite(&overlay[i].blendtype, sizeof(int), data);
+ engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
+ }
+ engine->FWrite(&clutslot, sizeof(int), data);
+ engine->FWrite(&drawreflections, sizeof(int), data);
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data);
+ engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data);
+ engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&sprite[j].x, sizeof(double), data);
+ engine->FWrite(&sprite[j].y, sizeof(double), data);
+ engine->FWrite(&sprite[j].texture, sizeof(int), data);
+ engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data);
+ engine->FWrite(&sprite[j].uDivW, sizeof(double), data);
+ engine->FWrite(&sprite[j].uDivH, sizeof(double), data);
+ engine->FWrite(&sprite[j].vMove, sizeof(double), data);
+ engine->FWrite(&sprite[j].hMove, sizeof(double), data);
+ engine->FWrite(&sprite[j].objectinteract, sizeof(char), data);
+ engine->FWrite(&sprite[j].view, sizeof(int), data);
+ engine->FWrite(&sprite[j].frame, sizeof(int), data);
+ engine->FWrite(&sprite[j].angle, sizeof(int), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ for (int k = 0; k < 4; ++k) {
+ engine->FWrite(&wallData[j].texture[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].solid[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].alpha[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].mask[k], sizeof(int), data);
+ }
+ engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data);
+ }
+ engine->FWrite(&raycastOn, sizeof(bool), data);
+ engine->FWrite(&heightmapOn, sizeof(bool), data);
+ engine->FWrite(&posX, sizeof(double), data);
+ engine->FWrite(&posY, sizeof(double), data);
+ engine->FWrite(&dirX, sizeof(double), data);
+ engine->FWrite(&dirY, sizeof(double), data);
+ engine->FWrite(&planeX, sizeof(double), data);
+ engine->FWrite(&planeY, sizeof(double), data);
+ engine->FWrite(&moveSpeed, sizeof(double), data);
+ engine->FWrite(&rotSpeed, sizeof(double), data);
+ if (raycastOn) { //If the raycaster is active, we have additional data to save.
+ for (int i = 0; i < mapWidth; ++i)
+ for (int j = 0; j < mapHeight; ++j) {
+ engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data);
+ engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data);
+ engine->FWrite(&ceilingMap [i][j], sizeof(int), data);
+ engine->FWrite(&floorMap [i][j], sizeof(int), data);
+ engine->FWrite(&heightMap [i][j], sizeof(int), data);
+ }
+ }
+ engine->FWrite(&textureSlot, sizeof(int), data);
+ engine->FWrite(&skybox, sizeof(int), data);
+ engine->FWrite(&ambientlight, sizeof(int), data);
+ }
+ if (event == AGSE_RESTOREGAME) {
+
+
+ for (int i = 0; i < MAX_OVERLAYS; ++i) {
+ engine->FRead(&overlay[i].sprite, sizeof(int), data);
+ engine->FRead(&overlay[i].spritemask, sizeof(int), data);
+ engine->FRead(&overlay[i].x, sizeof(int), data);
+ engine->FRead(&overlay[i].y, sizeof(int), data);
+ engine->FRead(&overlay[i].level, sizeof(int), data);
+ engine->FRead(&overlay[i].trans, sizeof(int), data);
+ engine->FRead(&overlay[i].blendtype, sizeof(int), data);
+ engine->FRead(&overlay[i].enabled, sizeof(bool), data);
+ }
+ engine->FRead(&clutslot, sizeof(int), data);
+ engine->FRead(&drawreflections, sizeof(int), data);
+ for (int j = 0; j < 256; ++j) {
+ engine->FRead(&cycle_remap[j], sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Objective Palette, for palette mixing.
+ engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data);
+ engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data);
+ engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Raycaster Sprite struct, 256 instances.
+ engine->FRead(&sprite[j].x, sizeof(double), data);
+ engine->FRead(&sprite[j].y, sizeof(double), data);
+ engine->FRead(&sprite[j].texture, sizeof(int), data);
+ engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data);
+ engine->FRead(&sprite[j].uDivW, sizeof(double), data);
+ engine->FRead(&sprite[j].uDivH, sizeof(double), data);
+ engine->FRead(&sprite[j].vMove, sizeof(double), data);
+ engine->FRead(&sprite[j].hMove, sizeof(double), data);
+ engine->FRead(&sprite[j].objectinteract, sizeof(char), data);
+ engine->FRead(&sprite[j].view, sizeof(int), data);
+ engine->FRead(&sprite[j].frame, sizeof(int), data);
+ engine->FRead(&sprite[j].angle, sizeof(int), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Raycaster wall type data.
+ for (int k = 0; k < 4; ++k) {
+ engine->FRead(&wallData[j].texture[k], sizeof(int), data);
+ engine->FRead(&wallData[j].solid[k], sizeof(int), data);
+ engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data);
+ engine->FRead(&wallData[j].alpha[k], sizeof(int), data);
+ engine->FRead(&wallData[j].blendtype[k], sizeof(int), data);
+ engine->FRead(&wallData[j].mask[k], sizeof(int), data);
+ }
+ engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data);
+ }
+ //Delete worldmap data if it exists.
+ engine->FRead(&raycastOn, sizeof(bool), data);
+ engine->FRead(&heightmapOn, sizeof(bool), data);
+ engine->FRead(&posX, sizeof(double), data);
+ engine->FRead(&posY, sizeof(double), data);
+ engine->FRead(&dirX, sizeof(double), data);
+ engine->FRead(&dirY, sizeof(double), data);
+ engine->FRead(&planeX, sizeof(double), data);
+ engine->FRead(&planeY, sizeof(double), data);
+ engine->FRead(&moveSpeed, sizeof(double), data);
+ engine->FRead(&rotSpeed, sizeof(double), data);
+ if (raycastOn) { //If the raycaster is currently running, we have additional data to load.
+ for (int i = 0; i < mapWidth; ++i) {
+ for (int j = 0; j < mapHeight; ++j) {
+ engine->FRead(&worldMap [i][j], sizeof(unsigned char), data);
+ engine->FRead(&lightMap [i][j], sizeof(unsigned char), data);
+ engine->FRead(&ceilingMap [i][j], sizeof(int), data);
+ engine->FRead(&floorMap [i][j], sizeof(int), data);
+ engine->FRead(&heightMap [i][j], sizeof(int), data);
+ seenMap [i][j] = 0;
+ }
+ }
+
+ //Reinitialize all the buffers and stuff.
+
+ }
+ engine->FRead(&textureSlot, sizeof(int), data);
+ if (textureSlot) MakeTextures(textureSlot);
+ engine->FRead(&skybox, sizeof(int), data);
+ engine->FRead(&ambientlight, sizeof(int), data);
+ LoadCLUT(clutslot);
+ }
+ if (event == AGSE_ENTERROOM) {
+ ResetRemapping();
+ delete[] Reflection.Objects;
+ Reflection.Objects = new objrefopt [engine->GetNumObjects()]();
+ }
+ return 0;
+}
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
diff --git a/engines/ags/plugins/ags_pal_render/pal_render.h b/engines/ags/plugins/ags_pal_render/pal_render.h
index 1d61dab866..1ea7951138 100644
--- a/engines/ags/plugins/ags_pal_render/pal_render.h
+++ b/engines/ags/plugins/ags_pal_render/pal_render.h
@@ -1,193 +1,193 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
-#define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
-
-#include "ags/lib/allegro.h"
-#include "ags/plugins/agsplugin.h"
-#include "common/algorithm.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define SCRIPT_FLOAT(x) int32 __script_float##x
-#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float))
-#define FLOAT_RETURN_TYPE int32
-#define RETURN_FLOAT(x) int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x
-
-struct PALSTRUCT {
- int r;
- int b;
- int g;
-};
-
-extern IAGSEngine *engine;
-extern unsigned char clut[65536];
-extern unsigned char cycle_remap [256];
-extern const int alphamultiply [4096];
-extern PALSTRUCT objectivepal[256];
-
-// this class exists solely to take advantage of g++'s
-// -fvisibility-inlines-hidden option, so that these
-// methods can be inlined without any trace or complaint
-class Mix {
-public:
-//unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha);
-//unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha);
- static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- //int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
- //int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
- //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
- int out_r, out_g, out_b;
- if (use_objpal == 0) {
- out_r = (objectivepal[rfg].r >> 1) *alpha + (palette[bg].r >> 1) *(255 - alpha);
- out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha);
- out_b = (objectivepal[rfg].b >> 1) *alpha + (palette[bg].b >> 1) *(255 - alpha);
- } else {
- out_r = (objectivepal[rfg].r >> 1) *alpha + (objectivepal[bg].r >> 1) *(255 - alpha);
- out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha);
- out_b = (objectivepal[rfg].b >> 1) *alpha + (objectivepal[bg].b >> 1) *(255 - alpha);
- }
- //char ralpha = MAX(0,MIN(63,alpha>>2));
- //unsigned char invralpha = 64-ralpha;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)];
- //int out_g = alphamultiply[((palette[fg].g) <<6) +ralpha] + alphamultiply[((palette[bg].g) <<6) +(invralpha)];
- //int out_b = alphamultiply[((palette[fg].b>>1)<<6) +ralpha] + alphamultiply[((palette[bg].b>>1)<<6) +(invralpha)];
- out_r = (out_r + 1 + (out_r >> 8)) >> 8;
- out_g = (out_g + 1 + (out_g >> 8)) >> 8;
- out_b = (out_b + 1 + (out_b >> 8)) >> 8;
- //out_r = (out_r + 1 + (out_r >> 6)) >> 6;
- //out_g = (out_g + 1 + (out_g >> 6)) >> 6;
- //out_b = (out_b + 1 + (out_b >> 6)) >> 6;
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char(*clutp) = clut;
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- }
-
- static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) {
- unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- int i = 0;
- //int dark_r = (((palette[fg].r>>1) * (intensity))>>8);
- //int dark_b = (((palette[fg].b>>1) * (intensity))>>8);
- //int dark_g = (((palette[fg].g) * (intensity))>>8);
- int dark_r = (((objectivepal[rfg].r >> 1) * (intensity)) >> 8);
- int dark_b = (((objectivepal[rfg].b >> 1) * (intensity)) >> 8);
- int dark_g = (((objectivepal[rfg].g) * (intensity)) >> 8);
- i = ((dark_r << 11) | (dark_g << 5) | dark_b);
- unsigned char (*clutp) = clut;
- return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- }
-
- static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap[bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- int add_r, add_b, add_g = 0;
- //char ralpha = MAX(0,MIN(63,alpha>>2));
- //add_r = (((palette[fg].r>>1) * (alpha))>>8);
- //add_b = (((palette[fg].b>>1) * (alpha))>>8);
- //add_g = (((palette[fg].g) * (alpha))>>8);
- add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8);
- add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8);
- add_g = (((objectivepal[rfg].g) * (alpha)) >> 8);
- //int a_g = MAX(0,MIN(63,alpha>>2));
- //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6);
- //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6);
- //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6);
- //int out_r = MIN(31,(palette[bg].r>>1) + add_r);
- //int out_g = MIN(63, palette[bg].g + add_g);
- //int out_b = MIN(31,(palette[bg].b>>1) + add_b);
- int out_r, out_g, out_b;
- if (use_objpal == 0) {
- out_r = MIN(31, (palette[bg].r >> 1) + add_r);
- out_g = MIN(63, palette[bg].g + add_g);
- out_b = MIN(31, (palette[bg].b >> 1) + add_b);
- } else {
- out_r = MIN(31, (objectivepal [bg].r >> 1) + add_r);
- out_g = MIN(63, objectivepal [bg].g + add_g);
- out_b = MIN(31, (objectivepal [bg].b >> 1) + add_b);
- }
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
- }
-
- static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- int mul_r, mul_b, mul_g = 0;
- int out_r, out_g, out_b = 0;
- if (use_objpal == 0) {
- mul_r = ((objectivepal[rfg].r >> 1) * (palette[rbg].r >> 1)) / 64;
- mul_b = ((objectivepal[rfg].b >> 1) * (palette[rbg].b >> 1)) / 64;
- mul_g = ((objectivepal[rfg].g * palette[rbg].g) / 64);
- out_r = ((palette[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
- out_g = (palette[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
- out_b = ((palette[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
- } else {
- mul_r = ((objectivepal[rfg].r >> 1) * (objectivepal[rbg].r >> 1)) / 64;
- mul_b = ((objectivepal[rfg].b >> 1) * (objectivepal[rbg].b >> 1)) / 64;
- mul_g = ((objectivepal[rfg].g * objectivepal[rbg].g) / 64);
-
- out_r = ((objectivepal[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
- out_g = (objectivepal[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
- out_b = ((objectivepal[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
- }
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
- }
-
-};
-
-unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b);
-
-unsigned short root(unsigned short x);
-float FastSin(float x);
-float FastCos(float x);
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
+#define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
+
+#include "ags/lib/allegro.h"
+#include "ags/plugins/agsplugin.h"
+#include "common/algorithm.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define SCRIPT_FLOAT(x) int32 __script_float##x
+#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float))
+#define FLOAT_RETURN_TYPE int32
+#define RETURN_FLOAT(x) int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x
+
+struct PALSTRUCT {
+ int r;
+ int b;
+ int g;
+};
+
+extern IAGSEngine *engine;
+extern unsigned char clut[65536];
+extern unsigned char cycle_remap [256];
+extern const int alphamultiply [4096];
+extern PALSTRUCT objectivepal[256];
+
+// this class exists solely to take advantage of g++'s
+// -fvisibility-inlines-hidden option, so that these
+// methods can be inlined without any trace or complaint
+class Mix {
+public:
+//unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha);
+//unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha);
+ static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ //int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
+ //int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
+ //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
+ int out_r, out_g, out_b;
+ if (use_objpal == 0) {
+ out_r = (objectivepal[rfg].r >> 1) *alpha + (palette[bg].r >> 1) *(255 - alpha);
+ out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha);
+ out_b = (objectivepal[rfg].b >> 1) *alpha + (palette[bg].b >> 1) *(255 - alpha);
+ } else {
+ out_r = (objectivepal[rfg].r >> 1) *alpha + (objectivepal[bg].r >> 1) *(255 - alpha);
+ out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha);
+ out_b = (objectivepal[rfg].b >> 1) *alpha + (objectivepal[bg].b >> 1) *(255 - alpha);
+ }
+ //char ralpha = MAX(0,MIN(63,alpha>>2));
+ //unsigned char invralpha = 64-ralpha;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)];
+ //int out_g = alphamultiply[((palette[fg].g) <<6) +ralpha] + alphamultiply[((palette[bg].g) <<6) +(invralpha)];
+ //int out_b = alphamultiply[((palette[fg].b>>1)<<6) +ralpha] + alphamultiply[((palette[bg].b>>1)<<6) +(invralpha)];
+ out_r = (out_r + 1 + (out_r >> 8)) >> 8;
+ out_g = (out_g + 1 + (out_g >> 8)) >> 8;
+ out_b = (out_b + 1 + (out_b >> 8)) >> 8;
+ //out_r = (out_r + 1 + (out_r >> 6)) >> 6;
+ //out_g = (out_g + 1 + (out_g >> 6)) >> 6;
+ //out_b = (out_b + 1 + (out_b >> 6)) >> 6;
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char(*clutp) = clut;
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ }
+
+ static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) {
+ unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ int i = 0;
+ //int dark_r = (((palette[fg].r>>1) * (intensity))>>8);
+ //int dark_b = (((palette[fg].b>>1) * (intensity))>>8);
+ //int dark_g = (((palette[fg].g) * (intensity))>>8);
+ int dark_r = (((objectivepal[rfg].r >> 1) * (intensity)) >> 8);
+ int dark_b = (((objectivepal[rfg].b >> 1) * (intensity)) >> 8);
+ int dark_g = (((objectivepal[rfg].g) * (intensity)) >> 8);
+ i = ((dark_r << 11) | (dark_g << 5) | dark_b);
+ unsigned char (*clutp) = clut;
+ return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ }
+
+ static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap[bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ int add_r, add_b, add_g = 0;
+ //char ralpha = MAX(0,MIN(63,alpha>>2));
+ //add_r = (((palette[fg].r>>1) * (alpha))>>8);
+ //add_b = (((palette[fg].b>>1) * (alpha))>>8);
+ //add_g = (((palette[fg].g) * (alpha))>>8);
+ add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8);
+ add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8);
+ add_g = (((objectivepal[rfg].g) * (alpha)) >> 8);
+ //int a_g = MAX(0,MIN(63,alpha>>2));
+ //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6);
+ //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6);
+ //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6);
+ //int out_r = MIN(31,(palette[bg].r>>1) + add_r);
+ //int out_g = MIN(63, palette[bg].g + add_g);
+ //int out_b = MIN(31,(palette[bg].b>>1) + add_b);
+ int out_r, out_g, out_b;
+ if (use_objpal == 0) {
+ out_r = MIN(31, (palette[bg].r >> 1) + add_r);
+ out_g = MIN(63, palette[bg].g + add_g);
+ out_b = MIN(31, (palette[bg].b >> 1) + add_b);
+ } else {
+ out_r = MIN(31, (objectivepal [bg].r >> 1) + add_r);
+ out_g = MIN(63, objectivepal [bg].g + add_g);
+ out_b = MIN(31, (objectivepal [bg].b >> 1) + add_b);
+ }
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+ }
+
+ static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ int mul_r, mul_b, mul_g = 0;
+ int out_r, out_g, out_b = 0;
+ if (use_objpal == 0) {
+ mul_r = ((objectivepal[rfg].r >> 1) * (palette[rbg].r >> 1)) / 64;
+ mul_b = ((objectivepal[rfg].b >> 1) * (palette[rbg].b >> 1)) / 64;
+ mul_g = ((objectivepal[rfg].g * palette[rbg].g) / 64);
+ out_r = ((palette[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
+ out_g = (palette[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
+ out_b = ((palette[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
+ } else {
+ mul_r = ((objectivepal[rfg].r >> 1) * (objectivepal[rbg].r >> 1)) / 64;
+ mul_b = ((objectivepal[rfg].b >> 1) * (objectivepal[rbg].b >> 1)) / 64;
+ mul_g = ((objectivepal[rfg].g * objectivepal[rbg].g) / 64);
+
+ out_r = ((objectivepal[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
+ out_g = (objectivepal[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
+ out_b = ((objectivepal[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
+ }
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+ }
+
+};
+
+unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b);
+
+unsigned short root(unsigned short x);
+float FastSin(float x);
+float FastCos(float x);
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
+
+#endif
diff --git a/engines/ags/plugins/ags_pal_render/raycast.cpp b/engines/ags/plugins/ags_pal_render/raycast.cpp
index 405c7550c7..2095c00916 100644
--- a/engines/ags/plugins/ags_pal_render/raycast.cpp
+++ b/engines/ags/plugins/ags_pal_render/raycast.cpp
@@ -1,1497 +1,1497 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "ags/lib/allegro.h"
-#include "ags/plugins/ags_pal_render/raycast.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define PI (3.1415926535f)
-
-//Variable Declaration
-bool raycastOn;
-double posX = 22.0, posY = 11.5; //x and y start position
-double dirX = -1.0, dirY = 0.0; //initial direction vector
-double planeX = 0.0, planeY = 0.77; //the 2d raycaster version of camera plane
-double moveSpeed = (1.0 / 60.0) * 3.0; //the constant value is in squares/second
-double rotSpeed = (1.0 / 60.0) * 2.0; //the constant value is in radians/second
-unsigned char worldMap[64][64];
-unsigned char lightMap[64][64];
-int ceilingMap[64][64];
-int floorMap[64][64];
-int heightMap[64][64];
-unsigned char seenMap[64][64];
-//int mapWidth;
-//int mapHeight;
-#define mapWidth 64
-#define mapHeight 64
-int textureSlot;
-int ambientlight;
-int ambientweight = 0;
-int ambientcolor = 0;
-int ambientcolorAmount = 0;
-
-Sprite sprite[numSprites] = {};
-
-
-#define sWidth 320
-#define sHeight 160
-
-int editorMap [sWidth][sHeight] = {};
-
-unsigned char texture[MAX_TEXTURES][texWidth * texHeight];
-
-wallType wallData[256] = {};
-
-//arrays used to sort the sprites
-int spriteOrder[numSprites];
-double spriteTransformX[numSprites];
-double spriteTransformY[numSprites];
-
-unsigned char **transcolorbuffer;
-unsigned char **transalphabuffer;
-double **transzbuffer;
-bool *transslicedrawn;
-int *transwallblendmode;
-double **ZBuffer;
-double *distTable;
-short *interactionmap;
-int skybox = 0;
-bool heightmapOn;
-
-int noclip = 0;
-
-int selectedX;
-int selectedY;
-unsigned char selectedColor;
-
-void Ray_SelectTile(int x, int y, unsigned char color) {
- if (x < 0 || x > mapWidth) selectedX = -1;
- else if (y < 0 || y > mapWidth) selectedY = -1;
- else {
- selectedX = x;
- selectedY = y;
- selectedColor = color;
- }
-}
-
-int Ray_HasSeenTile(int x, int y) {
- if (x < 0 || x > mapWidth) return -1;
- else if (y < 0 || y > mapWidth) return -1;
- return seenMap [x][y];
-}
-
-void Ray_SetNoClip(int value) {
- noclip = value;
-}
-
-int Ray_GetNoClip() {
- return noclip;
-}
-
-void Ray_DrawTile(int spr, int tile) {
- BITMAP *img = engine->GetSpriteGraphic(spr);
- unsigned char **sprarray = engine->GetRawBitmapSurface(img);
- for (int y = 0; y < 64; ++y)
- for (int x = 0; x < 64; ++x)
- sprarray [y][x] = texture [tile][(texWidth * y) + x];
- engine->ReleaseBitmapSurface(img);
-}
-
-void Ray_DrawOntoTile(int spr, int tile) {
- BITMAP *img = engine->GetSpriteGraphic(spr);
- unsigned char **sprarray = engine->GetRawBitmapSurface(img);
- for (int y = 0; y < 64; ++y)
- for (int x = 0; x < 64; ++x)
- texture [tile][(texWidth * y) + x] = sprarray [y][x];
- engine->ReleaseBitmapSurface(img);
-}
-
-int Ray_GetTileX_At(int x, int y) {
- if (x < 0 || x > 319 || y < 0 || y > 159) return -1;
- else return editorMap [x][y] >> 16;
-}
-
-int Ray_GetTileY_At(int x, int y) {
- if (x < 0 || x > 319 || y < 0 || y > 159) return -1;
- else return editorMap [x][y] & 0x0000FFFF;
-}
-
-void Ray_SetWallAt(int x, int y, int id) {
- if (x < 0 || x >= mapWidth) return;
- if (y < 0 || y >= mapHeight) return;
- worldMap [x][y] = id;
-}
-
-int Ray_GetWallAt(int x, int y) {
- if (x < 0 || x >= mapWidth) return -1;
- if (y < 0 || y >= mapHeight) return -1;
- return worldMap [x][y];
-}
-
-int Ray_GetAmbientWeight() {
- return ambientweight;
-}
-
-void Ray_SetAmbientLight(int value) {
- ambientlight = MIN(255, MAX(0, value));
-}
-
-void Ray_SetAmbientColor(int color, int amount) {
- ambientcolor = color;
- ambientcolorAmount = amount;
-}
-
-int Ray_GetAmbientLight() {
- return ambientlight;
-}
-double fsqrt(double y) {
- double x, z, tempf;
- unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
-
- tempf = y;
- *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
- x = tempf;
- z = y * 0.5; /* hoist out the �/2� */
- x = (1.5 * x) - (x * x) * (x * z); /* iteration formula */
- x = (1.5 * x) - (x * x) * (x * z);
- x = (1.5 * x) - (x * x) * (x * z);
- x = (1.5 * x) - (x * x) * (x * z);
- x = (1.5 * x) - (x * x) * (x * z);
- return x * y;
-}
-
-void Ray_SetWallHotspot(int id, char hotsp) {
- wallData[id].hotspotinteract = hotsp;
-}
-
-void Ray_SetWallTextures(int id, int n, int s, int w, int e) {
- wallData[id].texture[0] = n;
- wallData[id].texture[1] = s;
- wallData[id].texture[2] = w;
- wallData[id].texture[3] = e;
-}
-
-void Ray_SetWallSolid(int id, int n, int s, int w, int e) {
- wallData[id].solid [0] = MAX(0, MIN(n, 1));
- wallData[id].solid [1] = MAX(0, MIN(s, 1));
- wallData[id].solid [2] = MAX(0, MIN(w, 1));
- wallData[id].solid [3] = MAX(0, MIN(e, 1));
-}
-
-void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e) {
- wallData[id].ignorelighting [0] = MAX(0, MIN(n, 1));
- wallData[id].ignorelighting [1] = MAX(0, MIN(s, 1));
- wallData[id].ignorelighting [2] = MAX(0, MIN(w, 1));
- wallData[id].ignorelighting [3] = MAX(0, MIN(e, 1));
-}
-
-void Ray_SetWallAlpha(int id, int n, int s, int w, int e) {
- wallData[id].alpha [0] = MAX(0, MIN(n, 255));
- wallData[id].alpha [1] = MAX(0, MIN(s, 255));
- wallData[id].alpha [2] = MAX(0, MIN(w, 255));
- wallData[id].alpha [3] = MAX(0, MIN(e, 255));
-}
-
-void Ray_SetWallBlendType(int id, int n, int s, int w, int e) {
- wallData[id].blendtype [0] = MAX(0, MIN(n, 10));
- wallData[id].blendtype [1] = MAX(0, MIN(s, 10));
- wallData[id].blendtype [2] = MAX(0, MIN(w, 10));
- wallData[id].blendtype [3] = MAX(0, MIN(e, 10));
-}
-
-
-
-
-int Ray_GetWallHotspot(int id) {
- return wallData[id].hotspotinteract;
-}
-
-int Ray_GetWallTexture(int id, int dir) {
- return wallData[id].texture[dir];
-}
-
-int Ray_GetWallSolid(int id, int dir) {
- return wallData[id].solid [dir];
-}
-
-int Ray_GetWallIgnoreLighting(int id, int dir) {
- return wallData[id].ignorelighting [dir];
-}
-
-int Ray_GetWallAlpha(int id, int dir) {
- return wallData[id].alpha [dir];
-}
-
-int Ray_GetWallBlendType(int id, int dir) {
- return wallData[id].blendtype [dir];
-}
-
-
-
-
-
-FLOAT_RETURN_TYPE Ray_GetMoveSpeed() {
- float mSpeed = (float)moveSpeed;
- RETURN_FLOAT(mSpeed);
-}
-
-
-void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed)) {
- INIT_SCRIPT_FLOAT(speed);
- moveSpeed = (double)speed;
-}
-
-FLOAT_RETURN_TYPE Ray_GetRotSpeed() {
- float rSpeed = (float)rotSpeed;
- RETURN_FLOAT(rSpeed);
-}
-
-void Ray_SetRotSpeed(SCRIPT_FLOAT(speed)) {
- INIT_SCRIPT_FLOAT(speed);
- rotSpeed = (double)speed;
-}
-
-
-int Ray_GetLightAt(int x, int y) {
- return lightMap [x][y];
-}
-
-void Ray_SetLightAt(int x, int y, int light) {
- lightMap [x][y] = light;
-}
-
-void Ray_SetPlaneY(SCRIPT_FLOAT(y)) {
- INIT_SCRIPT_FLOAT(y);
- planeY = (double)y;
-}
-
-FLOAT_RETURN_TYPE Ray_GetPlaneY() {
- float pY = (float)planeY;
- RETURN_FLOAT(pY);
-}
-
-void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) {
- INIT_SCRIPT_FLOAT(x);
- INIT_SCRIPT_FLOAT(y);
- posX = (double)x;
- posY = (double)y;
-}
-
-FLOAT_RETURN_TYPE Ray_GetPlayerX() {
-
- float x = (float)posX;
- RETURN_FLOAT(x);
-}
-
-FLOAT_RETURN_TYPE Ray_GetPlayerY() {
- float y = (float)posY;
- RETURN_FLOAT(y);
-}
-
-int Ray_GetPlayerAngle() {
- double bgrad = atan2(dirY, dirX);
- int bgdeg = (int)(bgrad / PI * 180.0) + 180;
- return bgdeg % 360;
-}
-
-void Ray_SetPlayerAngle(int angle) {
- int realangle = angle % 360;
- if (realangle < 0) realangle += 360;
-
- int anglediff = realangle - Ray_GetPlayerAngle();
- double radians = 0.0174533 * anglediff;
- double oldDirX = dirX;
- dirX = dirX * cos(radians) - dirY * sin(radians);
- dirY = oldDirX * sin(radians) + dirY * cos(radians);
- double oldPlaneX = planeX;
- planeX = planeX * cos(radians) - planeY * sin(radians);
- planeY = oldPlaneX * sin(radians) + planeY * cos(radians);
-}
-
-
-void LoadHeightMap(int heightmapSlot) {
- int tempw = engine->GetSpriteWidth(heightmapSlot);
- int temph = engine->GetSpriteHeight(heightmapSlot);
- if (tempw != mapWidth || temph != mapHeight) engine->AbortGame("LoadHeightMap: Map sizes are mismatched!");
- BITMAP *heightmapBm = engine->GetSpriteGraphic(heightmapSlot);
- if (!heightmapBm) engine->AbortGame("LoadHeightMap: Cannot load sprite into memory.");
- unsigned char **hmArray = engine->GetRawBitmapSurface(heightmapBm);
-
- for (int i = 0; i < tempw; i++) {
- for (int j = 0; j < temph; j++) {
- heightMap[i][j] = hmArray[i][j];
- }
- }
- engine->ReleaseBitmapSurface(heightmapBm);
- heightmapOn = true;
-}
-
-void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot) {
- int tempw = engine->GetSpriteWidth(worldmapSlot);
- int temph = engine->GetSpriteHeight(worldmapSlot);
- BITMAP *worldmapBm = nullptr;
- BITMAP *lightmapBm = nullptr;
- BITMAP *floormapBm = nullptr;
- BITMAP *ceilingmapBm = nullptr;
- unsigned char **wmArray = nullptr;
- unsigned char **lmArray = nullptr;
- unsigned char **fmArray = nullptr;
- unsigned char **cmArray = nullptr;
- worldmapBm = engine->GetSpriteGraphic(worldmapSlot);
- if (!worldmapBm) engine->AbortGame("LoadMap: Couldn't load worldmap sprite into memory.");
- wmArray = engine->GetRawBitmapSurface(worldmapBm);
- if (engine->GetSpriteWidth(lightmapSlot) != tempw || engine->GetSpriteHeight(lightmapSlot) != temph) engine->AbortGame("LoadMap: Lightmap has different dimensions to worldmap.");
- else {
- lightmapBm = engine->GetSpriteGraphic(lightmapSlot);
- if (!lightmapBm) engine->AbortGame("LoadMap: Couldn't load lightmap sprite into memory.");
- lmArray = engine->GetRawBitmapSurface(lightmapBm);
- }
- if (engine->GetSpriteWidth(ceilingmapSlot) != tempw || engine->GetSpriteHeight(ceilingmapSlot) != temph) engine->AbortGame("LoadMap: Ceilingmap has different dimensions to worldmap.");
- else {
- ceilingmapBm = engine->GetSpriteGraphic(ceilingmapSlot);
- if (!ceilingmapBm) engine->AbortGame("LoadMap: Couldn't load ceilingmap sprite into memory.");
- cmArray = engine->GetRawBitmapSurface(ceilingmapBm);
- }
- if (engine->GetSpriteWidth(floormapSlot) != tempw || engine->GetSpriteHeight(floormapSlot) != temph) engine->AbortGame("LoadMap: Floormap has different dimensions to worldmap.");
- else {
- floormapBm = engine->GetSpriteGraphic(floormapSlot);
- if (!floormapBm) engine->AbortGame("LoadMap: Couldn't load floormap sprite into memory.");
- fmArray = engine->GetRawBitmapSurface(floormapBm);
- }
- for (int i = 0; i < tempw; i++) {
- for (int j = 0; j < temph; j++) {
- worldMap[i][j] = wmArray[i][j];
- lightMap[i][j] = lmArray[i][j];
- floorMap[i][j] = fmArray[i][j];
- ceilingMap[i][j] = cmArray[i][j];
- heightMap[i][j] = 0;
- seenMap[i][j] = 0;
- }
- }
- engine->ReleaseBitmapSurface(worldmapBm);
- engine->ReleaseBitmapSurface(lightmapBm);
- engine->ReleaseBitmapSurface(ceilingmapBm);
- engine->ReleaseBitmapSurface(floormapBm);
- //LoadHeightMap (31); //debug only
-}
-
-FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id) {
- float scale = (float)sprite[id].uDivW;
- RETURN_FLOAT(scale);
-}
-
-void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale)) {
- INIT_SCRIPT_FLOAT(scale);
- sprite[id].uDivW = scale;
-}
-
-FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id) {
- float scale = (float)sprite[id].uDivH;
- RETURN_FLOAT(scale);
-}
-
-void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale)) {
- INIT_SCRIPT_FLOAT(scale);
- sprite[id].uDivH = scale;
-}
-
-int Ray_GetSpriteAlpha(int id) {
- return sprite[id].alpha;
-}
-
-void Ray_SetSpriteAlpha(int id, int alpha) {
- sprite[id].alpha = alpha;
-}
-
-int Ray_GetSpritePic(int id) {
- return sprite[id].texture;
-}
-
-void Ray_SetSpritePic(int id, int slot) {
- sprite[id].texture = slot;
-}
-
-
-
-int Ray_GetSpriteAngle(int id) {
- return sprite[id].angle;
-}
-
-void Ray_SetSpriteAngle(int id, int angle) {
- sprite[id].angle = angle % 360;
-}
-
-int Ray_GetSpriteInteractObj(int id) {
- return sprite[id].objectinteract;
-}
-
-void Ray_SetSpriteView(int id, int view) {
- sprite[id].view = view;
-}
-
-void Ray_SetSpriteBlendType(int id, int type) {
- sprite[id].blendmode = type;
-}
-
-int Ray_GetSpriteBlendType(int id) {
- return sprite[id].blendmode;
-}
-
-
-int Ray_GetSpriteView(int id) {
- return sprite[id].view;
-}
-
-void Ray_SetSpriteFrame(int id, int frame) {
- sprite[id].frame = frame;
-}
-
-int Ray_GetSpriteFrame(int id) {
- return sprite[id].frame;
-}
-
-void Ray_SetSpriteInteractObj(int id, int obj) {
- sprite[id].objectinteract = obj;
-}
-
-void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) {
- INIT_SCRIPT_FLOAT(x);
- INIT_SCRIPT_FLOAT(y);
- sprite[id].x = x;
- sprite[id].y = y;
-}
-
-void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove)) {
- INIT_SCRIPT_FLOAT(vMove);
- sprite[id].vMove = vMove;
-}
-
-
-FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id) {
- float x = (float)sprite[id].vMove;
- RETURN_FLOAT(x);
-}
-
-FLOAT_RETURN_TYPE Ray_GetSpriteX(int id) {
- float x = (float)sprite[id].x;
- RETURN_FLOAT(x);
-}
-
-FLOAT_RETURN_TYPE Ray_GetSpriteY(int id) {
- float y = (float)sprite[id].y;
- RETURN_FLOAT(y);
-}
-
-void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove)) {
- INIT_SCRIPT_FLOAT(x);
- INIT_SCRIPT_FLOAT(y);
- INIT_SCRIPT_FLOAT(scale_x);
- INIT_SCRIPT_FLOAT(scale_y);
- INIT_SCRIPT_FLOAT(vMove);
- sprite[id].x = x;
- sprite[id].y = y;
- sprite[id].texture = slot;
- sprite[id].alpha = alpha;
- sprite[id].blendmode = blendmode;
- sprite[id].uDivW = scale_x;
- sprite[id].uDivH = scale_y;
- sprite[id].vMove = vMove;
-}
-
-//function used to sort the sprites
-void combSort(int *order, double *dist, int amount);
-
-void MakeTextures(int slot) {
- textureSlot = slot;
- int sourceWidth = engine->GetSpriteWidth(slot);
- int sourceHeight = engine->GetSpriteHeight(slot);
- int max = (sourceWidth / texWidth) * (sourceHeight / texHeight);
- if (max > MAX_TEXTURES) engine->AbortGame("MakeTextures: Source file has too many tiles to load.");
- BITMAP *texspr = engine->GetSpriteGraphic(slot);
- unsigned char **texbuffer = engine->GetRawBitmapSurface(texspr);
- int numTilesX = sourceWidth / texWidth;
- int numTilesY = sourceHeight / texHeight;
- //int totaltiles = numTilesX * numTilesY;
- for (int numX = 0; numX < numTilesX; ++numX) {
- for (int numY = 0; numY < numTilesY; ++numY) {
- for (int x = 0; x < texWidth; ++x)
- for (int y = 0; y < texHeight; ++y) {
- texture[(numY * numTilesX) + numX][(texWidth * y) + x] = texbuffer [y + (texHeight * numY)][x + (texWidth * numX)];
- }
- }
- }
- engine->ReleaseBitmapSurface(texspr);
-
- for (int i = 0; i < 11; i++) {
- for (int j = 0; j < 4; j++) {
- wallData[i].texture[j] = i;
- if (i == 10) wallData[i].texture[j] = 11;
- if (i > 0) wallData[i].solid[j] = 1;
- else wallData[i].solid[j] = 0;
- if (i != 10) wallData[i].alpha[j] = 255;
- else {
- wallData[i].alpha[j] = 128;
- wallData[i].blendtype[j] = 0;
- wallData[i].solid[j] = 0;
- }
- }
- }
- wallData[1].texture[0] = 1;
- wallData[1].texture[1] = 2;
- wallData[1].texture[2] = 3;
- wallData[1].texture[3] = 4;
- wallData[1].solid[0] = 0;
-
-
-
-}
-
-//double ZBuffer[screenWidth][screenHeight];
-
-void Ray_SetFloorAt(int x, int y, int tex) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return;
- else floorMap[x][y] = tex;
-}
-
-void Ray_SetCeilingAt(int x, int y, int tex) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return;
- else ceilingMap[x][y] = tex;
-}
-
-int Ray_GetCeilingAt(int x, int y) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
- else return ceilingMap [x][y];
-}
-
-
-int Ray_GetFloorAt(int x, int y) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
- else return floorMap [x][y];
-}
-
-
-int Ray_GetLightingAt(int x, int y) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
- else {
- int lighting = 0;
- if (ceilingMap[x][y] == 0) {
- lighting = ambientlight;
- if (ambientlight < lightMap [x][y]) lighting = lightMap[x][y];
- }
- return lighting;
- }
-}
-
-void Ray_SetLightingAt(int x, int y, unsigned char lighting) {
- if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return;
- else {
- lightMap [x][y] = lighting;
- }
-}
-
-void Ray_SetSkyBox(int slot) {
- BITMAP *test = engine->GetSpriteGraphic(slot);
- if (test) {
- skybox = slot;
- } else engine->AbortGame("Ray_SetSkybox: No such sprite!");
-}
-
-int Ray_GetSkyBox(int slot) {
- return skybox;
-}
-
-int Ray_GetHotspotAt(int x, int y) {
- if (!interactionmap) return -1;
- else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1;
- else return interactionmap [x * sWidth + y] & 0x00FF;
-}
-
-int Ray_GetObjectAt(int x, int y) {
- if (!interactionmap) return -1;
- else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1;
- else return interactionmap [x * sWidth + y] >> 8;
-}
-
-FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y) {
- float falsereturn = -1.0f;
- if (!ZBuffer) {
- RETURN_FLOAT(falsereturn);
- } else if (x > sWidth || x < 0 || y > sHeight || y < 0) {
- RETURN_FLOAT(falsereturn);
- } else {
-
- float zbuf = (float)ZBuffer[x][y];
- RETURN_FLOAT(zbuf);
- }
-}
-
-void Init_Raycaster() {
- if (ZBuffer)
- return;
- //if (!worldMap) return;
- transcolorbuffer = new unsigned char *[sWidth];
- transalphabuffer = new unsigned char *[sWidth];
- transslicedrawn = new bool[sWidth]();
- transzbuffer = new double*[sWidth];
- transwallblendmode = new int [mapWidth]();
- ZBuffer = new double*[sWidth];
- distTable = new double[sHeight + (sHeight >> 1)];
- interactionmap = new short[sWidth * sHeight]();
- for (int y = 0; y < sHeight + (sHeight >> 1); y++) {
- distTable [y] = sHeight / (2.0 * y - sHeight);
- }
- for (int x = 0; x < sWidth; x++) {
- transcolorbuffer[x] = new unsigned char [sHeight * (mapWidth)]();
- transalphabuffer[x] = new unsigned char [sHeight * (mapWidth)]();
- transzbuffer[x] = new double [sHeight * (mapWidth)]();
- ZBuffer[x] = new double [sHeight]();
- transslicedrawn [x] = false;
- }
-}
-
-bool rendering;
-void Raycast_Render(int slot) {
- ambientweight = 0;
- raycastOn = true;
- double playerrad = atan2(dirY, dirX) + (2.0 * PI);
- rendering = true;
- int32 w = sWidth, h = sHeight;
- BITMAP *screen = engine->GetSpriteGraphic(slot);
- if (!screen) engine->AbortGame("Raycast_Render: No valid sprite to draw on.");
- engine->GetBitmapDimensions(screen, &w, &h, nullptr);
- BITMAP *sbBm = engine->GetSpriteGraphic(skybox);
- if (!sbBm) engine->AbortGame("Raycast_Render: No valid skybox sprite.");
- if (skybox > 0) {
- //int bgdeg = (int)((playerrad / PI) * 180.0) + 180;
- int xoffset = (int)(playerrad * 320.0);
- BITMAP *virtsc = engine->GetVirtualScreen();
- engine->SetVirtualScreen(screen);
- xoffset = abs(xoffset % w);
- if (xoffset > 0) {
- engine->BlitBitmap(xoffset - 320, 1, sbBm, false);
- }
- engine->BlitBitmap(xoffset, 1, sbBm, false);
- engine->SetVirtualScreen(virtsc);
- }
- int transwallcount = 0;
- unsigned char **buffer = engine->GetRawBitmapSurface(screen);
- for (int x = 0; x < w; x++) {
- transslicedrawn [x] = false;
- for (int y = 0; y < h; y++) {
- ZBuffer[x][y] = 0;
- }
- }
- //int multiplier = mapWidth;
- memset(interactionmap, 0, sizeof(short) * (sHeight * sWidth));
- //start the main loop
- for (int x = 0; x < w; x++) {
- transwallcount = 0;
- //calculate ray position and direction
- double cameraX = 2 * x / double(w) - 1; //x-coordinate in camera space
- double rayPosX = posX;
- double rayPosY = posY;
- double rayDirX = dirX + planeX * cameraX;
- double rayDirY = dirY + planeY * cameraX;
-
- //which box of the map we're in
- int mapX = int(rayPosX);
- int mapY = int(rayPosY);
-
- //length of ray from current position to next x or y-side
- double sideDistX;
- double sideDistY;
-
- //length of ray from one x or y-side to next x or y-side
- double deltaDistX = fsqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
- double deltaDistY = fsqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
- double perpWallDist = 0.0;
-
- //what direction to step in x or y-direction (either +1 or -1)
- int stepX;
- int stepY;
- int prevmapX = 0;
- int prevmapY = 0;
- int hit = 0; //was there a wall hit?
- int side = 0; //was a NS or a EW wall hit?
-
- //calculate step and initial sideDist
- if (rayDirX < 0) {
- stepX = -1;
- sideDistX = (rayPosX - mapX) * deltaDistX;
- } else {
- stepX = 1;
- sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
- }
- if (rayDirY < 0) {
- stepY = -1;
- sideDistY = (rayPosY - mapY) * deltaDistY;
- } else {
- stepY = 1;
- sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
- }
- // Perform DDA
- bool deeper = true;
- bool opposite = true;
- bool oppositedrawn = false;
- double wallX = 0; // Where exactly the wall was hit
- int drawStart;
- int drawEnd = 0;
- while (hit == 0 && deeper == true) {
- if (opposite) {
- rayDirX = -rayDirX;
- rayDirY = -rayDirY;
- stepX = -stepX;
- stepY = -stepY;
- if (sideDistX < sideDistY) side = 0;
- else side = 1;
- } else if (sideDistX < sideDistY) { // jump to next map square, OR in x-direction, OR in y-direction
- sideDistX += deltaDistX;
- mapX += stepX;
- mapX = abs(mapX) % mapHeight;
- side = 0;
- if (oppositedrawn && worldMap[mapX][mapY] > 8) {
- opposite = true;
- oppositedrawn = false;
- rayDirX = -rayDirX;
- rayDirY = -rayDirY;
- stepX = -stepX;
- stepY = -stepY;
- if (sideDistX < sideDistY) side = 0;
- else side = 1;
- } else {
- oppositedrawn = false;
- opposite = false;
- }
- } else {
- sideDistY += deltaDistY;
- mapY += stepY;
- mapY = abs(mapY) % mapHeight;
- side = 1;
- if (oppositedrawn && worldMap[mapX][mapY] > 8) {
- opposite = true;
- oppositedrawn = false;
- rayDirX = -rayDirX;
- rayDirY = -rayDirY;
- stepX = -stepX;
- stepY = -stepY;
- if (sideDistX < sideDistY) side = 0;
- else side = 1;
- } else {
- oppositedrawn = false;
- opposite = false;
- }
- }
- int texside = 0;
- if (rayDirX > 0 && side == 0) texside = 0;
- if (rayDirX < 0 && side == 0) texside = 1;
- if (rayDirY > 0 && side == 1) texside = 2;
- if (rayDirY < 0 && side == 1) texside = 3;
-
- //set this tile as seen.
- seenMap[mapX][mapY] = 1;
- //Check if ray has hit a wall
- if (wallData[worldMap[mapX][mapY]].texture[texside]) {
- bool ambientpixels = false;
- hit = 1; //Set this to true so that by default, it's impossible to hang the engine.
- deeper = false; //Set this to false so that we don't go deeper than we need to.
-
- //Calculate distance of perpendicular ray (oblique distance will give fisheye effect!)
- if (side == 0) perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
- else perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
- //Calculate height of line to draw on screen
- int lineHeight = abs(int(h / perpWallDist));
-
- //calculate lowest and highest pixel to fill in current stripe
- drawStart = -lineHeight / 2 + h / 2;
- if (drawStart < 0) drawStart = 0;
- drawEnd = lineHeight / 2 + h / 2;
- if (drawEnd >= h) drawEnd = h;
- //texturing calculations
- int texNum = wallData[worldMap[mapX][mapY]].texture[texside] - 1; //1 subtracted from it so that texture 0 can be used!
- if (!opposite) {
- //calculate value of wallX
- if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX;
- else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY;
- } else {
- if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / -rayDirY) * -rayDirX;
- else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / -rayDirX) * -rayDirY;
- }
- wallX -= floor((wallX));
-
- //x coordinate on the texture
- int wall_light = 255;
- int texX = int(wallX * double(texWidth));
- if (side == 0 && rayDirX > 0) texX = texWidth - texX - 1;
- if (side == 1 && rayDirY < 0) texX = texWidth - texX - 1;
- bool do_ambient = false;
- if (!opposite) {
- if (rayDirX > 0 && side == 0) {
- wall_light = lightMap [(int)mapX - 1 % mapWidth][(int)mapY] << 5;
- if (ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] <= 1) do_ambient = true;
- else if (texture[ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true;
- }
- if (rayDirX < 0 && side == 0) {
- wall_light = lightMap [(int)mapX + 1 % mapWidth][(int)mapY] << 5;
- if (ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] <= 1) do_ambient = true;
- else if (texture[ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] - 1][(texWidth * texX) + 0] == 0) do_ambient = true;
-
- }
- if (rayDirY > 0 && side == 1) {
- wall_light = lightMap [(int)mapX][(int)mapY - 1 % mapHeight] << 5;
- if (ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] <= 1) do_ambient = true;
- else if (texture[ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] - 1][(texWidth * 63) + texX] == 0) do_ambient = true;
- }
- if (rayDirY < 0 && side == 1) {
- wall_light = lightMap [(int)mapX][(int)mapY + 1 % mapHeight] << 5;
- if (ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] <= 1) do_ambient = true;
- else if (texture[ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] - 1][(texWidth * 0) + 63 - texX] == 0) do_ambient = true;
- }
- } else if (opposite) {
- wall_light = lightMap [(int)mapX][(int)mapY] << 5;
- if (ceilingMap [(int)mapX][(int)mapY] <= 1) do_ambient = true;
- if (rayDirX > 0 && side == 0) {
- if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true;
- }
- if (rayDirX < 0 && side == 0) {
- if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * texX) + 63] == 0) do_ambient = true;
- }
- if (rayDirY > 0 && side == 1) {
- if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 0) + (63 - texX)] == 0) do_ambient = true;
- }
- if (rayDirY < 0 && side == 1) {
- if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 63) + texX] == 0) do_ambient = true;
- }
- }
- if (do_ambient) {
- ambientpixels = true;
- wall_light = MAX(wall_light, ambientlight);
- }
- wall_light = MIN(255, MAX(0, wall_light));
- bool alphastripe = false;
- for (int y = drawStart; y < drawEnd; y++) {
- if (ZBuffer[x][y] > perpWallDist || ZBuffer[x][y] == 0) { //We can draw.
- int d = y * 256 - h * 128 + lineHeight * 128; //256 and 128 factors to avoid floats
- int texY = ((d * texHeight) / lineHeight) / 256;
- int color = texture[texNum][texWidth * texY + texX];
- if (color > 0) {
- if (ambientpixels && ambientcolor) color = Mix::MixColorMultiply(ambientcolor, color, ambientcolorAmount, 1);
- if (!wallData[worldMap[mapX][mapY]].ignorelighting[texside] && wall_light < 255) color = Mix::MixColorLightLevel(color, wall_light);
- if (wallData[worldMap[mapX][mapY]].alpha[texside] == 255 && wallData[worldMap[mapX][mapY]].mask[texside] == 0) {
- buffer[y][x] = color;
- if (ambientpixels) ambientweight++;
- //SET THE ZBUFFER FOR THE SPRITE CASTING
- ZBuffer[x][y] = perpWallDist; //perpendicular distance is used
- interactionmap [x * sWidth + y] = wallData[worldMap[mapX][mapY]].hotspotinteract;
- editorMap [x][y] = ((short)mapX) << 16 | ((short)mapY);
- } else {
- if (transslicedrawn[x] == false) {
- memset(transcolorbuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth));
- memset(transalphabuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth));
- //memset (transzbuffer[x],0,sizeof(double)*(sHeight*mapWidth));
- transslicedrawn[x] = true;
- }
- transwallblendmode[transwallcount] = wallData[worldMap[mapX][mapY]].blendtype[texside];
- int transwalloffset = transwallcount * h;
- transcolorbuffer[x][transwalloffset + y] = color;
- if (ambientpixels) ambientweight++;
- if (wallData[worldMap[mapX][mapY]].mask[texside] == 0) transalphabuffer[x][transwalloffset + y] = wallData[worldMap[mapX][mapY]].alpha[texside];
- else {
- transalphabuffer[x][transwalloffset + y] = (wallData[worldMap[mapX][mapY]].alpha[texside] + texture[wallData[worldMap[mapX][mapY]].mask[texside]][texWidth * texY + texX]) >> 1;
- }
- transzbuffer[x][transwalloffset + y] = perpWallDist;
- hit = 0;
- deeper = true;
- alphastripe = true;
- }
- } else {
- //We found transparency, we have to draw deeper.
- deeper = true;
- hit = 0;
- }
- if ((int)mapX == selectedX && (int)mapY == selectedY) {
- if (texX == 0 || texX == 63 || texY == 0 || texY == 63) {
- buffer[y][x] = selectedColor;
- ZBuffer [x][y] = perpWallDist;
- }
- }
-
- }
- }
- if (alphastripe) {
- if (transwallcount < mapWidth) {
- transwallcount++;
- }
- alphastripe = false;
- }
- if (opposite) {
- if (mapX == 0 || mapX == mapWidth || mapY == 0 || mapY == mapHeight) {
- deeper = false;
- hit = 0;
- }
- oppositedrawn = true;
- if (deeper) opposite = false;
- rayDirX = -rayDirX;
- rayDirY = -rayDirY;
- stepX = -stepX;
- stepY = -stepY;
- } else if (!opposite && deeper) {
- opposite = true;
- prevmapX = mapX;
- prevmapY = mapY;
- }
- //End of wall drawing functions.
- } else if (opposite) {
- opposite = false;
- //oppositedrawn = false;
- rayDirX = -rayDirX;
- rayDirY = -rayDirY;
- stepX = -stepX;
- stepY = -stepY;
- } else if (!opposite && deeper) {
- opposite = true;
- prevmapX = mapX;
- prevmapY = mapY;
- }
- //End of loop.
- }
-
- // Unused variables
- (void)prevmapX;
- (void)prevmapY;
-
- //FLOOR CASTING
-
- double floorXWall, floorYWall; //x, y position of the floor texel at the bottom of the wall
- //4 different wall directions possible
- if (side == 0 && rayDirX > 0) {
- floorXWall = mapX;
- floorYWall = mapY + wallX;
- if (opposite) floorXWall = floorXWall + 1.0;
- } else if (side == 0 && rayDirX < 0) {
- floorXWall = mapX + 1.0;
- floorYWall = mapY + wallX;
- if (opposite) floorXWall = floorXWall - 1.0;
- } else if (side == 1 && rayDirY > 0) {
- floorXWall = mapX + wallX;
- floorYWall = mapY;
- if (opposite) floorYWall = floorYWall + 1.0;
- } else {
- floorXWall = mapX + wallX;
- floorYWall = mapY + 1.0;
- if (opposite) floorYWall = floorYWall - 1.0;
- }
-
- double distWall, distPlayer, currentDist;
-
- distWall = perpWallDist;
- distPlayer = 0.0;
- if (drawEnd < 0)
- drawEnd = h - 1; //becomes < 0 when the integer overflows
- //draw the floor from drawEnd to the bottom of the screen
- int drawdist = h;
- int expandeddraw = h >> 1;
- for (int y = drawEnd; y < drawdist + expandeddraw; y++) {
- //currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead
- currentDist = distTable[y];
- if (y > h - 1) {
- //if (!heightMap) break;
- double weight = (currentDist - distPlayer) / (distWall - distPlayer);
-
- double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
- double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;
-
- int floorTexX, floorTexY;
- int cmapX = (int)currentFloorX;
- if (cmapX > mapWidth - 1) cmapX = mapWidth - 1;
- if (cmapX < 0) cmapX = 0;
- int cmapY = (int)currentFloorY;
- if (cmapY > mapHeight - 1) cmapY = mapHeight - 1;
- if (cmapY < 0) cmapY = 0;
- if (heightMap[cmapX][cmapY] - 1 < 1) continue;
- int lighting = lightMap [cmapX][cmapY] << 5;
- lighting = MIN(255, MAX(0, lighting));
- floorTexX = int(currentFloorX * texWidth) % texWidth;
- floorTexY = int(currentFloorY * texHeight) % texHeight;
- int floorcolor = 0;
- int ceilingcolor = 0;
- int texpos = texWidth * floorTexY + floorTexX;
- if (ceilingMap[cmapX][cmapY] - 1 > 0) {
- ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
- }
- if (floorMap[cmapX][cmapY] - 1 > 0) {
- floorcolor = texture[floorMap[cmapX][cmapY] - 1][texpos];
- } else continue;
- if (ceilingcolor == 0) {
- lighting = MAX(lighting, ambientlight);
- ambientweight ++;
- }
- if (lighting < 255) {
- if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting);
- }
-
- if (/*heightMap &&*/ floorcolor > 0) {
- if (heightMap[cmapX][cmapY] - 1 > 0) {
- int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texpos] / currentDist);
- if (raisedfloorstart > h - 1) continue;
- if (raisedfloorstart < 0) raisedfloorstart = 0;
- for (int ny = raisedfloorstart; ny < y; ny++) {
- if (ny < h && (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0)) {
- ZBuffer[x][ny] = currentDist; //perpendicular distance is used
- buffer[ny][x] = floorcolor;
- interactionmap [x * sWidth + ny] = 0;
- editorMap [x][ny] = ((short)mapX) << 16 | ((short)mapY);
- }
- }
- if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++;
- }
- }
- } else {
- double weight = (currentDist - distPlayer) / (distWall - distPlayer);
-
- double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
- double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;
-
- int floorTexX, floorTexY;
- int cmapX = (int)currentFloorX % mapWidth;
- if (cmapX < 0) cmapX = 0;
- int cmapY = (int)currentFloorY % mapHeight;
- if (cmapY < 0) cmapY = 0;
- int lighting = lightMap [cmapX][cmapY] << 5;
- lighting = MIN(255, MAX(0, lighting));
- floorTexX = int(currentFloorX * texWidth) % texWidth;
- floorTexY = int(currentFloorY * texHeight) % texHeight;
- int floorcolor = 0;
- int ceilingcolor = 0;
- if (floorMap[cmapX][cmapY] - 1 > 0) {
- floorcolor = texture[floorMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
- }
- if (ceilingMap[cmapX][cmapY] - 1 > 0) {
- ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
- }
- if (ceilingcolor == 0) {
- lighting = MAX(lighting, ambientlight);
- ambientweight++;
- }
- if (lighting < 255) {
- if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting);
- if (ceilingcolor) ceilingcolor = Mix::MixColorLightLevel(ceilingcolor, lighting);
- }
-
- if (/*heightMap &&*/ floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) {
- if (heightMap[cmapX][cmapY] - 1 > 0) {
- int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX] / currentDist);
- if (raisedfloorstart > h - 1) continue;
- if (raisedfloorstart < 0) raisedfloorstart = 0;
- for (int ny = raisedfloorstart; ny < y; ny++) {
- if (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0) {
- ZBuffer[x][ny] = currentDist; //perpendicular distance is used
- buffer[ny][x] = floorcolor;
- interactionmap [x * sWidth + ny] = 0;
- editorMap [x][ny] = ((short)cmapX) << 16 | ((short)cmapY);
- }
- }
- if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++;
- }
- }
- //floor
- //ceiling (symmetrical!)
- //SET THE ZBUFFER FOR THE SPRITE CASTING
- if (floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) {
- ZBuffer[x][y] = currentDist; //perpendicular distance is used
- buffer[y][x] = floorcolor;
- editorMap [x][y] = ((short)cmapX) << 16 | ((short)cmapY);
- } else ZBuffer[x][y] = 9999999999999.0;
- if (currentDist < ZBuffer[x][h - y] || ZBuffer[x][h - y] == 0) {
- if (ceilingcolor > 0) {
- ZBuffer[x][h - y] = currentDist; //perpendicular distance is used
- buffer[h - y][x] = ceilingcolor;
- } else ZBuffer[x][h - y] = 999999999999.0;
- editorMap [x][h - y] = ((short)cmapX) << 16 | ((short)cmapY);
- }
- interactionmap [x * sWidth + y] = 0;
- interactionmap [x * sWidth + (h - y)] = 0;
- if ((int)cmapX == selectedX && (int)cmapY == selectedY) {
- if (floorTexX == 0 || floorTexX == 63 || floorTexY == 0 || floorTexY == 63) {
- buffer[y][x] = selectedColor;
- ZBuffer [x][y] = perpWallDist;
- buffer[h - y][x] = selectedColor;
- ZBuffer [x][h - y] = perpWallDist;
- }
- }
-
-
- }
- }
- //TRANSLUCENT WALL RENDERING
- if (transslicedrawn[x] == true) {
- for (int y = 0; y < h; y++) {
- for (int transwalldrawn = 0; transwalldrawn < transwallcount; transwalldrawn++) {
- int transwalloffset = transwalldrawn * h;
- int color = transcolorbuffer[x][transwalloffset + y];
- if (color != 0) {
- if (transwallblendmode[transwalldrawn] == 0) buffer[y][x] = Mix::MixColorAlpha(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]); //paint pixel if it isn't black, black is the invisible color
- else if (transwallblendmode[transwalldrawn] == 1) buffer[y][x] = Mix::MixColorAdditive(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]);
- //if (ZBuffer[x][y] > transzbuffer[transwalldrawn*h+y]) ZBuffer[x][y] = transzbuffer[transwalldrawn*h+y]; //put the sprite on the zbuffer so we can draw around it.
- }
- }
- }
- }
- //End of wall loop.
- }
-
-
- //SPRITE CASTING
- //sort sprites from far to close
-
- //Initialize Sprites for casting.
- double invDet = 1.0 / (planeX * dirY - dirX * planeY);
- for (int i = 0; i < numSprites; i++) {
- spriteOrder[i] = i;
- spriteTransformY[i] = ((posX - sprite[i].x) * (posX - sprite[i].x) + (posY - sprite[i].y) * (posY - sprite[i].y));
- }
- combSort(spriteOrder, spriteTransformY, numSprites);
- for (int i = 0; i < numSprites; i++) {
- double spriteX = sprite[spriteOrder[i]].x - posX;
- double spriteY = sprite[spriteOrder[i]].y - posY;
- spriteTransformX[i] = invDet * (dirY * spriteX - dirX * spriteY);
- spriteTransformY[i] = invDet * (-planeY * spriteX + planeX * spriteY);
- }
-
- int transwalldraw = 0;
- //after sorting the sprites, do the projection and draw them
- for (int i = 0; i < numSprites; i++) {
- int flipped = 0;
- if (sprite[spriteOrder[i]].view != 0) {
-
- double sprrad = atan2(sprite[spriteOrder[i]].y - posY, sprite[spriteOrder[i]].x - posX);
- int sprdeg = (int)(sprrad / 3.1415 * 180.0);
- sprdeg = ((sprdeg + 180) + sprite[spriteOrder[i]].angle) % 360;
- int loop = 0;
- if (sprdeg > 336 || sprdeg < 23) loop = 0;
- else if (sprdeg > 22 && sprdeg < 68) loop = 6;
- else if (sprdeg > 67 && sprdeg < 113) loop = 1;
- else if (sprdeg > 112 && sprdeg < 158) loop = 7;
- else if (sprdeg > 157 && sprdeg < 203) loop = 3;
- else if (sprdeg > 202 && sprdeg < 248) loop = 5;
- else if (sprdeg > 247 && sprdeg < 293) loop = 2;
- else if (sprdeg > 292 && sprdeg < 337) loop = 4;
- AGSViewFrame *vf = engine->GetViewFrame(sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame);
- if (vf == nullptr) engine->AbortGame("Raycast_Render: Unable to load viewframe of sprite.");
- else {
- sprite[spriteOrder[i]].texture = vf->pic;
- int (*sfGetGameParameter)(int, int, int, int);
- sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
- flipped = sfGetGameParameter(13, sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame);
- }
- }
- //translate sprite position to relative to camera
- //double spriteX = sprite[spriteOrder[i]].x - posX;
- //double spriteY = sprite[spriteOrder[i]].y - posY;
-
- //transform sprite with the inverse camera matrix
- // [ planeX dirX ] -1 [ dirY -dirX ]
- // [ ] = 1/(planeX*dirY-dirX*planeY) * [ ]
- // [ planeY dirY ] [ -planeY planeX ]
-
- //double invDet = 1.0 / (planeX * dirY - dirX * planeY); //required for correct matrix multiplication
- //double spriteX = sprite[spriteOrder[i]].x - posX;
- //double spriteY = sprite[spriteOrder[i]].y - posY;
- //double transformX = invDet * (dirY * spriteX - dirX * spriteY);
- //double transformY = invDet * (-planeY * spriteX + planeX * spriteY); //this is actually the depth inside the screen, that what Z is in 3D
-
- int spriteScreenX = int((w / 2) * (1 + spriteTransformX[i] / spriteTransformY[i]));
-
- //parameters for scaling and moving the sprites
- BITMAP *spritetexbm = engine->GetSpriteGraphic(sprite[spriteOrder[i]].texture);
- unsigned char **spritetex = engine->GetRawBitmapSurface(spritetexbm);
- int sprw = engine->GetSpriteWidth(sprite[spriteOrder[i]].texture);
- int sprh = engine->GetSpriteHeight(sprite[spriteOrder[i]].texture);
-
- double uDiv = ((double)sprw / (double)texWidth) + sprite[spriteOrder[i]].uDivW;
- double vDiv = ((double)sprh / (double)texHeight) + sprite[spriteOrder[i]].uDivH;
- double vMove = sprite[spriteOrder[i]].vMove + ((double)texHeight - (double)sprh) * 1.6;
- double hMove = sprite[spriteOrder[i]].hMove;
- int vMoveScreen = int(vMove / spriteTransformY[i]);
- int hMoveScreen = int(hMove / spriteTransformY[i]);
- //calculate height of the sprite on screen
- int spriteHeight = abs(int(h / (spriteTransformY[i]) * vDiv)) ; //using "transformY" instead of the real distance prevents fisheye
- //calculate lowest and highest pixel to fill in current stripe
- int drawStartY = -spriteHeight / 2 + h / 2 + vMoveScreen;
- if (drawStartY < 0) drawStartY = 0;
- int drawEndY = spriteHeight / 2 + h / 2 + vMoveScreen;
- if (drawEndY >= h) drawEndY = h - 1;
-
- //calculate width of the sprite
- int spriteWidth = abs(int (h / (spriteTransformY[i]) * uDiv)) ;
- int drawStartX = -spriteWidth / 2 + spriteScreenX + hMoveScreen;
- if (drawStartX < 0) drawStartX = 0;
- int drawEndX = spriteWidth / 2 + spriteScreenX + hMoveScreen;
- if (drawEndX >= w) drawEndX = w - 1;
- int spr_light = lightMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] << 5;
- spr_light = MIN(255, MAX(0, spr_light));
- int floorTexX = int(sprite[spriteOrder[i]].x * texWidth) % texWidth;
- int floorTexY = int(sprite[spriteOrder[i]].y * texHeight) % texHeight;
- if (ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] == 0) {
- spr_light = MAX(spr_light, ambientlight);
- } else if (texture[ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] - 1][texWidth * floorTexY + floorTexX] == 0) spr_light = MAX(spr_light, ambientlight);
- //loop through every vertical stripe of the sprite on screen
-
-
- for (int stripe = drawStartX; stripe < drawEndX; stripe++) {
- transwalldraw = 0;
- //int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * texWidth / spriteWidth) / 256;
- int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * sprw / spriteWidth) / 256;
- if (texX >= sprw || texX < 0) continue;
- if (flipped) texX = sprw - texX;
- //the conditions in the if are:
- //1) it's in front of camera plane so you don't see things behind you
- //2) it's on the screen (left)
- //3) it's on the screen (right)
- //4) ZBuffer, with perpendicular distance
- if (spriteTransformY[i] > 0 && stripe > 0 && stripe < w)
- for (int y = drawStartY; y < drawEndY; y++) { //for every pixel of the current stripe
- if (spriteTransformY[i] < ZBuffer[stripe][y]) {
- if (transslicedrawn[stripe]) while ((transzbuffer[stripe][transwalldraw * h + y] > spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0) && (transwalldraw < transwallcount)) transwalldraw++;
- int d = (y - vMoveScreen) * 256 - h * 128 + spriteHeight * 128; //256 and 128 factors to avoid floats
- //int texY = ((d * texHeight) / spriteHeight) / 256;
- int texY = ((d * sprh) / spriteHeight) / 256;
- if (texY >= sprh || texY < 0) continue;
- //unsigned char color = texture[sprite[spriteOrder[i]].texture][texWidth * texY + texX]; //get current color from the texture
- unsigned char color = spritetex[texY][texX]; //get current color from the texture
- if (color != 0) {
- if (sprite[spriteOrder[i]].alpha < 255) {
- if (sprite[spriteOrder[i]].blendmode == 0) color = Mix::MixColorAlpha(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha);
- if (sprite[spriteOrder[i]].blendmode == 1) color = Mix::MixColorAdditive(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha);
- }
- color = Mix::MixColorLightLevel(color, spr_light);
- if (transzbuffer[stripe][transwalldraw * h + y] < spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0 && transslicedrawn[stripe] && transcolorbuffer[stripe][transwalldraw * h + y] > 0 && transalphabuffer[stripe][transwalldraw * h + y] > 0) {
- if (transwallblendmode[transwalldraw] == 0) color = Mix::MixColorAlpha(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]);
- else if (transwallblendmode[transwalldraw] == 1) color = Mix::MixColorAdditive(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]);
- buffer[y][stripe] = color;
- ZBuffer[stripe][y] = transzbuffer[stripe][transwalldraw * h + y];
- } else {
- buffer[y][stripe] = color; //paint pixel if it isn't black, black is the invisible color
- ZBuffer[stripe][y] = spriteTransformY[i]; //put the sprite on the zbuffer so we can draw around it.
- }
- interactionmap [stripe * sWidth + y] = sprite[spriteOrder[i]].objectinteract << 8;
- }
- }
- }
- }
- engine->ReleaseBitmapSurface(spritetexbm);
- }
- engine->ReleaseBitmapSurface(screen);
- engine->NotifySpriteUpdated(slot);
- rendering = false;
-
-}
-
-void QuitCleanup() {
- if (!rendering) {
- for (int i = 0; i < sWidth; ++i) {
- if (transcolorbuffer[i])delete [] transcolorbuffer[i];
- if (transalphabuffer[i])delete [] transalphabuffer[i];
- if (transzbuffer[i])delete [] transzbuffer[i];
- if (ZBuffer[i]) delete [] ZBuffer[i];
- }
- if (transcolorbuffer) delete [] transcolorbuffer;
- if (transalphabuffer) delete [] transalphabuffer;
- if (transzbuffer) delete [] transzbuffer;
- if (ZBuffer) delete [] ZBuffer;
- if (transwallblendmode) delete [] transwallblendmode;
- if (interactionmap) delete [] interactionmap;
- }
-}
-
-void MoveForward() {
- double newposx = 0;
- if (dirX > 0) newposx = 0.1 + posX + dirX * moveSpeed;
- else newposx = -0.1 + posX + dirX * moveSpeed;
- int texsidex = 0;
- int inside_texsidex = 0;
- double newposy = 0;
- if (dirY > 0) newposy = 0.1 + posY + dirY * moveSpeed;
- else newposy = -0.1 + posY + dirY * moveSpeed;
- int texsidey = 0;
- int inside_texsidey = 0;
- bool inside = false;
- if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true;
- if (dirX > 0 && !inside) {
- texsidex = 0;
- inside_texsidex = 1;
- } else if (dirX > 0) {
- texsidex = 1;
- inside_texsidex = 0;
- }
- if (dirX < 0 && !inside) {
- texsidex = 1;
- inside_texsidex = 0;
- } else if (dirX < 0) {
- texsidex = 0;
- inside_texsidex = 1;
- }
-
- if (dirY > 0 && !inside) {
- texsidey = 2;
- inside_texsidey = 3;
- } else if (dirY > 0) {
- texsidey = 3;
- inside_texsidey = 2;
- }
- if (dirY < 0 && !inside) {
- texsidey = 3;
- inside_texsidey = 2;
- } else if (dirY < 0) {
- texsidey = 2;
- inside_texsidey = 3;
- }
-
- if (!noclip && !inside) {
- if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed;
- if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed;
- } else if (!noclip && inside) {
- posX += dirX * moveSpeed;
- posY += dirY * moveSpeed;
- } else {
- if (int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed;
- if (int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed;
- }
-}
-
-void MoveBackward() {
- double newposx = 0;
- if (dirX > 0) newposx = -0.1 + posX - dirX * moveSpeed;
- else newposx = 0.1 + posX - dirX * moveSpeed;
- int texsidex = 0;
- int inside_texsidex = 0;
- double newposy = 0;
- if (dirY > 0) newposy = -0.1 + posY - dirY * moveSpeed;
- else newposy = 0.1 + posY - dirY * moveSpeed;
- int texsidey = 0;
- int inside_texsidey = 0;
- bool inside = false;
- if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true;
- if (dirX > 0 && !inside) {
- texsidex = 1;
- inside_texsidex = 0;
- } else if (dirX > 0) {
- texsidex = 0;
- inside_texsidex = 1;
- }
- if (dirX < 0 && !inside) {
- texsidex = 0;
- inside_texsidex = 1;
- } else if (dirX < 0) {
- texsidex = 1;
- inside_texsidex = 0;
- }
-
- if (dirY > 0 && !inside) {
- texsidey = 3;
- inside_texsidey = 2;
- } else if (dirY > 0) {
- texsidey = 2;
- inside_texsidey = 3;
- }
- if (dirY < 0 && !inside) {
- texsidey = 2;
- inside_texsidey = 3;
- } else if (dirY < 0) {
- texsidey = 3;
- inside_texsidey = 2;
- }
-
- if ((int)posX == (int)newposy && (int)posY == (int)newposy) inside = true;
- if (!noclip && !inside) {
- if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed;
- if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed;
- } else if (!noclip && inside) {
- posX -= dirX * moveSpeed;
- posY -= dirY * moveSpeed;
- } else {
- if (int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed;
- if (int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed;
- }
-}
-
-
-
-/*
-void MoveBackward ()
-{
- double newposx;
- if (dirX > 0) newposx = -0.2 + posX - dirX * moveSpeed;
- else newposx = 0.2 + posX - dirX * moveSpeed;
- double newposy;
- if (dirY > 0) newposy = -0.2 + posY - dirY * moveSpeed;
- else newposy = 0.2 + posY - dirY * moveSpeed;
- if(worldMap[int(newposx)][int(posY)] == false || worldMap[int(newposx)][int(posY)] > 8) posX -= dirX * moveSpeed;
- if(worldMap[int(posX)][int(newposy)] == false || worldMap[int(posX)][int(newposy)] > 8) posY -= dirY * moveSpeed;
-}
-*/
-
-void RotateLeft() {
- double oldDirX = dirX;
- dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed);
- dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed);
- double oldPlaneX = planeX;
- planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);
- planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
-}
-
-void RotateRight() {
- double oldDirX = dirX;
- dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed);
- dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed);
- double oldPlaneX = planeX;
- planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
- planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
-}
-
-//sort algorithm
-void combSort(int *order, double *dist, int amount) {
- int gap = amount;
- bool swapped = false;
- while (gap > 1 || swapped) {
- //shrink factor 1.3
- gap = (gap * 10) / 13;
- if (gap == 9 || gap == 10) gap = 11;
- if (gap < 1) gap = 1;
- swapped = false;
- for (int i = 0; i < amount - gap; i++) {
- int j = i + gap;
- if (dist[i] < dist[j]) {
- SWAP(dist[i], dist[j]);
- SWAP(order[i], order[j]);
- swapped = true;
- }
- }
- }
-}
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
-
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ags/lib/allegro.h"
+#include "ags/plugins/ags_pal_render/raycast.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define PI (3.1415926535f)
+
+//Variable Declaration
+bool raycastOn;
+double posX = 22.0, posY = 11.5; //x and y start position
+double dirX = -1.0, dirY = 0.0; //initial direction vector
+double planeX = 0.0, planeY = 0.77; //the 2d raycaster version of camera plane
+double moveSpeed = (1.0 / 60.0) * 3.0; //the constant value is in squares/second
+double rotSpeed = (1.0 / 60.0) * 2.0; //the constant value is in radians/second
+unsigned char worldMap[64][64];
+unsigned char lightMap[64][64];
+int ceilingMap[64][64];
+int floorMap[64][64];
+int heightMap[64][64];
+unsigned char seenMap[64][64];
+//int mapWidth;
+//int mapHeight;
+#define mapWidth 64
+#define mapHeight 64
+int textureSlot;
+int ambientlight;
+int ambientweight = 0;
+int ambientcolor = 0;
+int ambientcolorAmount = 0;
+
+Sprite sprite[numSprites] = {};
+
+
+#define sWidth 320
+#define sHeight 160
+
+int editorMap [sWidth][sHeight] = {};
+
+unsigned char texture[MAX_TEXTURES][texWidth * texHeight];
+
+wallType wallData[256] = {};
+
+//arrays used to sort the sprites
+int spriteOrder[numSprites];
+double spriteTransformX[numSprites];
+double spriteTransformY[numSprites];
+
+unsigned char **transcolorbuffer;
+unsigned char **transalphabuffer;
+double **transzbuffer;
+bool *transslicedrawn;
+int *transwallblendmode;
+double **ZBuffer;
+double *distTable;
+short *interactionmap;
+int skybox = 0;
+bool heightmapOn;
+
+int noclip = 0;
+
+int selectedX;
+int selectedY;
+unsigned char selectedColor;
+
+void Ray_SelectTile(int x, int y, unsigned char color) {
+ if (x < 0 || x > mapWidth) selectedX = -1;
+ else if (y < 0 || y > mapWidth) selectedY = -1;
+ else {
+ selectedX = x;
+ selectedY = y;
+ selectedColor = color;
+ }
+}
+
+int Ray_HasSeenTile(int x, int y) {
+ if (x < 0 || x > mapWidth) return -1;
+ else if (y < 0 || y > mapWidth) return -1;
+ return seenMap [x][y];
+}
+
+void Ray_SetNoClip(int value) {
+ noclip = value;
+}
+
+int Ray_GetNoClip() {
+ return noclip;
+}
+
+void Ray_DrawTile(int spr, int tile) {
+ BITMAP *img = engine->GetSpriteGraphic(spr);
+ unsigned char **sprarray = engine->GetRawBitmapSurface(img);
+ for (int y = 0; y < 64; ++y)
+ for (int x = 0; x < 64; ++x)
+ sprarray [y][x] = texture [tile][(texWidth * y) + x];
+ engine->ReleaseBitmapSurface(img);
+}
+
+void Ray_DrawOntoTile(int spr, int tile) {
+ BITMAP *img = engine->GetSpriteGraphic(spr);
+ unsigned char **sprarray = engine->GetRawBitmapSurface(img);
+ for (int y = 0; y < 64; ++y)
+ for (int x = 0; x < 64; ++x)
+ texture [tile][(texWidth * y) + x] = sprarray [y][x];
+ engine->ReleaseBitmapSurface(img);
+}
+
+int Ray_GetTileX_At(int x, int y) {
+ if (x < 0 || x > 319 || y < 0 || y > 159) return -1;
+ else return editorMap [x][y] >> 16;
+}
+
+int Ray_GetTileY_At(int x, int y) {
+ if (x < 0 || x > 319 || y < 0 || y > 159) return -1;
+ else return editorMap [x][y] & 0x0000FFFF;
+}
+
+void Ray_SetWallAt(int x, int y, int id) {
+ if (x < 0 || x >= mapWidth) return;
+ if (y < 0 || y >= mapHeight) return;
+ worldMap [x][y] = id;
+}
+
+int Ray_GetWallAt(int x, int y) {
+ if (x < 0 || x >= mapWidth) return -1;
+ if (y < 0 || y >= mapHeight) return -1;
+ return worldMap [x][y];
+}
+
+int Ray_GetAmbientWeight() {
+ return ambientweight;
+}
+
+void Ray_SetAmbientLight(int value) {
+ ambientlight = MIN(255, MAX(0, value));
+}
+
+void Ray_SetAmbientColor(int color, int amount) {
+ ambientcolor = color;
+ ambientcolorAmount = amount;
+}
+
+int Ray_GetAmbientLight() {
+ return ambientlight;
+}
+double fsqrt(double y) {
+ double x, z, tempf;
+ unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
+
+ tempf = y;
+ *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
+ x = tempf;
+ z = y * 0.5; /* hoist out the �/2� */
+ x = (1.5 * x) - (x * x) * (x * z); /* iteration formula */
+ x = (1.5 * x) - (x * x) * (x * z);
+ x = (1.5 * x) - (x * x) * (x * z);
+ x = (1.5 * x) - (x * x) * (x * z);
+ x = (1.5 * x) - (x * x) * (x * z);
+ return x * y;
+}
+
+void Ray_SetWallHotspot(int id, char hotsp) {
+ wallData[id].hotspotinteract = hotsp;
+}
+
+void Ray_SetWallTextures(int id, int n, int s, int w, int e) {
+ wallData[id].texture[0] = n;
+ wallData[id].texture[1] = s;
+ wallData[id].texture[2] = w;
+ wallData[id].texture[3] = e;
+}
+
+void Ray_SetWallSolid(int id, int n, int s, int w, int e) {
+ wallData[id].solid [0] = MAX(0, MIN(n, 1));
+ wallData[id].solid [1] = MAX(0, MIN(s, 1));
+ wallData[id].solid [2] = MAX(0, MIN(w, 1));
+ wallData[id].solid [3] = MAX(0, MIN(e, 1));
+}
+
+void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e) {
+ wallData[id].ignorelighting [0] = MAX(0, MIN(n, 1));
+ wallData[id].ignorelighting [1] = MAX(0, MIN(s, 1));
+ wallData[id].ignorelighting [2] = MAX(0, MIN(w, 1));
+ wallData[id].ignorelighting [3] = MAX(0, MIN(e, 1));
+}
+
+void Ray_SetWallAlpha(int id, int n, int s, int w, int e) {
+ wallData[id].alpha [0] = MAX(0, MIN(n, 255));
+ wallData[id].alpha [1] = MAX(0, MIN(s, 255));
+ wallData[id].alpha [2] = MAX(0, MIN(w, 255));
+ wallData[id].alpha [3] = MAX(0, MIN(e, 255));
+}
+
+void Ray_SetWallBlendType(int id, int n, int s, int w, int e) {
+ wallData[id].blendtype [0] = MAX(0, MIN(n, 10));
+ wallData[id].blendtype [1] = MAX(0, MIN(s, 10));
+ wallData[id].blendtype [2] = MAX(0, MIN(w, 10));
+ wallData[id].blendtype [3] = MAX(0, MIN(e, 10));
+}
+
+
+
+
+int Ray_GetWallHotspot(int id) {
+ return wallData[id].hotspotinteract;
+}
+
+int Ray_GetWallTexture(int id, int dir) {
+ return wallData[id].texture[dir];
+}
+
+int Ray_GetWallSolid(int id, int dir) {
+ return wallData[id].solid [dir];
+}
+
+int Ray_GetWallIgnoreLighting(int id, int dir) {
+ return wallData[id].ignorelighting [dir];
+}
+
+int Ray_GetWallAlpha(int id, int dir) {
+ return wallData[id].alpha [dir];
+}
+
+int Ray_GetWallBlendType(int id, int dir) {
+ return wallData[id].blendtype [dir];
+}
+
+
+
+
+
+FLOAT_RETURN_TYPE Ray_GetMoveSpeed() {
+ float mSpeed = (float)moveSpeed;
+ RETURN_FLOAT(mSpeed);
+}
+
+
+void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed)) {
+ INIT_SCRIPT_FLOAT(speed);
+ moveSpeed = (double)speed;
+}
+
+FLOAT_RETURN_TYPE Ray_GetRotSpeed() {
+ float rSpeed = (float)rotSpeed;
+ RETURN_FLOAT(rSpeed);
+}
+
+void Ray_SetRotSpeed(SCRIPT_FLOAT(speed)) {
+ INIT_SCRIPT_FLOAT(speed);
+ rotSpeed = (double)speed;
+}
+
+
+int Ray_GetLightAt(int x, int y) {
+ return lightMap [x][y];
+}
+
+void Ray_SetLightAt(int x, int y, int light) {
+ lightMap [x][y] = light;
+}
+
+void Ray_SetPlaneY(SCRIPT_FLOAT(y)) {
+ INIT_SCRIPT_FLOAT(y);
+ planeY = (double)y;
+}
+
+FLOAT_RETURN_TYPE Ray_GetPlaneY() {
+ float pY = (float)planeY;
+ RETURN_FLOAT(pY);
+}
+
+void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) {
+ INIT_SCRIPT_FLOAT(x);
+ INIT_SCRIPT_FLOAT(y);
+ posX = (double)x;
+ posY = (double)y;
+}
+
+FLOAT_RETURN_TYPE Ray_GetPlayerX() {
+
+ float x = (float)posX;
+ RETURN_FLOAT(x);
+}
+
+FLOAT_RETURN_TYPE Ray_GetPlayerY() {
+ float y = (float)posY;
+ RETURN_FLOAT(y);
+}
+
+int Ray_GetPlayerAngle() {
+ double bgrad = atan2(dirY, dirX);
+ int bgdeg = (int)(bgrad / PI * 180.0) + 180;
+ return bgdeg % 360;
+}
+
+void Ray_SetPlayerAngle(int angle) {
+ int realangle = angle % 360;
+ if (realangle < 0) realangle += 360;
+
+ int anglediff = realangle - Ray_GetPlayerAngle();
+ double radians = 0.0174533 * anglediff;
+ double oldDirX = dirX;
+ dirX = dirX * cos(radians) - dirY * sin(radians);
+ dirY = oldDirX * sin(radians) + dirY * cos(radians);
+ double oldPlaneX = planeX;
+ planeX = planeX * cos(radians) - planeY * sin(radians);
+ planeY = oldPlaneX * sin(radians) + planeY * cos(radians);
+}
+
+
+void LoadHeightMap(int heightmapSlot) {
+ int tempw = engine->GetSpriteWidth(heightmapSlot);
+ int temph = engine->GetSpriteHeight(heightmapSlot);
+ if (tempw != mapWidth || temph != mapHeight) engine->AbortGame("LoadHeightMap: Map sizes are mismatched!");
+ BITMAP *heightmapBm = engine->GetSpriteGraphic(heightmapSlot);
+ if (!heightmapBm) engine->AbortGame("LoadHeightMap: Cannot load sprite into memory.");
+ unsigned char **hmArray = engine->GetRawBitmapSurface(heightmapBm);
+
+ for (int i = 0; i < tempw; i++) {
+ for (int j = 0; j < temph; j++) {
+ heightMap[i][j] = hmArray[i][j];
+ }
+ }
+ engine->ReleaseBitmapSurface(heightmapBm);
+ heightmapOn = true;
+}
+
+void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot) {
+ int tempw = engine->GetSpriteWidth(worldmapSlot);
+ int temph = engine->GetSpriteHeight(worldmapSlot);
+ BITMAP *worldmapBm = nullptr;
+ BITMAP *lightmapBm = nullptr;
+ BITMAP *floormapBm = nullptr;
+ BITMAP *ceilingmapBm = nullptr;
+ unsigned char **wmArray = nullptr;
+ unsigned char **lmArray = nullptr;
+ unsigned char **fmArray = nullptr;
+ unsigned char **cmArray = nullptr;
+ worldmapBm = engine->GetSpriteGraphic(worldmapSlot);
+ if (!worldmapBm) engine->AbortGame("LoadMap: Couldn't load worldmap sprite into memory.");
+ wmArray = engine->GetRawBitmapSurface(worldmapBm);
+ if (engine->GetSpriteWidth(lightmapSlot) != tempw || engine->GetSpriteHeight(lightmapSlot) != temph) engine->AbortGame("LoadMap: Lightmap has different dimensions to worldmap.");
+ else {
+ lightmapBm = engine->GetSpriteGraphic(lightmapSlot);
+ if (!lightmapBm) engine->AbortGame("LoadMap: Couldn't load lightmap sprite into memory.");
+ lmArray = engine->GetRawBitmapSurface(lightmapBm);
+ }
+ if (engine->GetSpriteWidth(ceilingmapSlot) != tempw || engine->GetSpriteHeight(ceilingmapSlot) != temph) engine->AbortGame("LoadMap: Ceilingmap has different dimensions to worldmap.");
+ else {
+ ceilingmapBm = engine->GetSpriteGraphic(ceilingmapSlot);
+ if (!ceilingmapBm) engine->AbortGame("LoadMap: Couldn't load ceilingmap sprite into memory.");
+ cmArray = engine->GetRawBitmapSurface(ceilingmapBm);
+ }
+ if (engine->GetSpriteWidth(floormapSlot) != tempw || engine->GetSpriteHeight(floormapSlot) != temph) engine->AbortGame("LoadMap: Floormap has different dimensions to worldmap.");
+ else {
+ floormapBm = engine->GetSpriteGraphic(floormapSlot);
+ if (!floormapBm) engine->AbortGame("LoadMap: Couldn't load floormap sprite into memory.");
+ fmArray = engine->GetRawBitmapSurface(floormapBm);
+ }
+ for (int i = 0; i < tempw; i++) {
+ for (int j = 0; j < temph; j++) {
+ worldMap[i][j] = wmArray[i][j];
+ lightMap[i][j] = lmArray[i][j];
+ floorMap[i][j] = fmArray[i][j];
+ ceilingMap[i][j] = cmArray[i][j];
+ heightMap[i][j] = 0;
+ seenMap[i][j] = 0;
+ }
+ }
+ engine->ReleaseBitmapSurface(worldmapBm);
+ engine->ReleaseBitmapSurface(lightmapBm);
+ engine->ReleaseBitmapSurface(ceilingmapBm);
+ engine->ReleaseBitmapSurface(floormapBm);
+ //LoadHeightMap (31); //debug only
+}
+
+FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id) {
+ float scale = (float)sprite[id].uDivW;
+ RETURN_FLOAT(scale);
+}
+
+void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale)) {
+ INIT_SCRIPT_FLOAT(scale);
+ sprite[id].uDivW = scale;
+}
+
+FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id) {
+ float scale = (float)sprite[id].uDivH;
+ RETURN_FLOAT(scale);
+}
+
+void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale)) {
+ INIT_SCRIPT_FLOAT(scale);
+ sprite[id].uDivH = scale;
+}
+
+int Ray_GetSpriteAlpha(int id) {
+ return sprite[id].alpha;
+}
+
+void Ray_SetSpriteAlpha(int id, int alpha) {
+ sprite[id].alpha = alpha;
+}
+
+int Ray_GetSpritePic(int id) {
+ return sprite[id].texture;
+}
+
+void Ray_SetSpritePic(int id, int slot) {
+ sprite[id].texture = slot;
+}
+
+
+
+int Ray_GetSpriteAngle(int id) {
+ return sprite[id].angle;
+}
+
+void Ray_SetSpriteAngle(int id, int angle) {
+ sprite[id].angle = angle % 360;
+}
+
+int Ray_GetSpriteInteractObj(int id) {
+ return sprite[id].objectinteract;
+}
+
+void Ray_SetSpriteView(int id, int view) {
+ sprite[id].view = view;
+}
+
+void Ray_SetSpriteBlendType(int id, int type) {
+ sprite[id].blendmode = type;
+}
+
+int Ray_GetSpriteBlendType(int id) {
+ return sprite[id].blendmode;
+}
+
+
+int Ray_GetSpriteView(int id) {
+ return sprite[id].view;
+}
+
+void Ray_SetSpriteFrame(int id, int frame) {
+ sprite[id].frame = frame;
+}
+
+int Ray_GetSpriteFrame(int id) {
+ return sprite[id].frame;
+}
+
+void Ray_SetSpriteInteractObj(int id, int obj) {
+ sprite[id].objectinteract = obj;
+}
+
+void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) {
+ INIT_SCRIPT_FLOAT(x);
+ INIT_SCRIPT_FLOAT(y);
+ sprite[id].x = x;
+ sprite[id].y = y;
+}
+
+void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove)) {
+ INIT_SCRIPT_FLOAT(vMove);
+ sprite[id].vMove = vMove;
+}
+
+
+FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id) {
+ float x = (float)sprite[id].vMove;
+ RETURN_FLOAT(x);
+}
+
+FLOAT_RETURN_TYPE Ray_GetSpriteX(int id) {
+ float x = (float)sprite[id].x;
+ RETURN_FLOAT(x);
+}
+
+FLOAT_RETURN_TYPE Ray_GetSpriteY(int id) {
+ float y = (float)sprite[id].y;
+ RETURN_FLOAT(y);
+}
+
+void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove)) {
+ INIT_SCRIPT_FLOAT(x);
+ INIT_SCRIPT_FLOAT(y);
+ INIT_SCRIPT_FLOAT(scale_x);
+ INIT_SCRIPT_FLOAT(scale_y);
+ INIT_SCRIPT_FLOAT(vMove);
+ sprite[id].x = x;
+ sprite[id].y = y;
+ sprite[id].texture = slot;
+ sprite[id].alpha = alpha;
+ sprite[id].blendmode = blendmode;
+ sprite[id].uDivW = scale_x;
+ sprite[id].uDivH = scale_y;
+ sprite[id].vMove = vMove;
+}
+
+//function used to sort the sprites
+void combSort(int *order, double *dist, int amount);
+
+void MakeTextures(int slot) {
+ textureSlot = slot;
+ int sourceWidth = engine->GetSpriteWidth(slot);
+ int sourceHeight = engine->GetSpriteHeight(slot);
+ int max = (sourceWidth / texWidth) * (sourceHeight / texHeight);
+ if (max > MAX_TEXTURES) engine->AbortGame("MakeTextures: Source file has too many tiles to load.");
+ BITMAP *texspr = engine->GetSpriteGraphic(slot);
+ unsigned char **texbuffer = engine->GetRawBitmapSurface(texspr);
+ int numTilesX = sourceWidth / texWidth;
+ int numTilesY = sourceHeight / texHeight;
+ //int totaltiles = numTilesX * numTilesY;
+ for (int numX = 0; numX < numTilesX; ++numX) {
+ for (int numY = 0; numY < numTilesY; ++numY) {
+ for (int x = 0; x < texWidth; ++x)
+ for (int y = 0; y < texHeight; ++y) {
+ texture[(numY * numTilesX) + numX][(texWidth * y) + x] = texbuffer [y + (texHeight * numY)][x + (texWidth * numX)];
+ }
+ }
+ }
+ engine->ReleaseBitmapSurface(texspr);
+
+ for (int i = 0; i < 11; i++) {
+ for (int j = 0; j < 4; j++) {
+ wallData[i].texture[j] = i;
+ if (i == 10) wallData[i].texture[j] = 11;
+ if (i > 0) wallData[i].solid[j] = 1;
+ else wallData[i].solid[j] = 0;
+ if (i != 10) wallData[i].alpha[j] = 255;
+ else {
+ wallData[i].alpha[j] = 128;
+ wallData[i].blendtype[j] = 0;
+ wallData[i].solid[j] = 0;
+ }
+ }
+ }
+ wallData[1].texture[0] = 1;
+ wallData[1].texture[1] = 2;
+ wallData[1].texture[2] = 3;
+ wallData[1].texture[3] = 4;
+ wallData[1].solid[0] = 0;
+
+
+
+}
+
+//double ZBuffer[screenWidth][screenHeight];
+
+void Ray_SetFloorAt(int x, int y, int tex) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return;
+ else floorMap[x][y] = tex;
+}
+
+void Ray_SetCeilingAt(int x, int y, int tex) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return;
+ else ceilingMap[x][y] = tex;
+}
+
+int Ray_GetCeilingAt(int x, int y) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
+ else return ceilingMap [x][y];
+}
+
+
+int Ray_GetFloorAt(int x, int y) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
+ else return floorMap [x][y];
+}
+
+
+int Ray_GetLightingAt(int x, int y) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1;
+ else {
+ int lighting = 0;
+ if (ceilingMap[x][y] == 0) {
+ lighting = ambientlight;
+ if (ambientlight < lightMap [x][y]) lighting = lightMap[x][y];
+ }
+ return lighting;
+ }
+}
+
+void Ray_SetLightingAt(int x, int y, unsigned char lighting) {
+ if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return;
+ else {
+ lightMap [x][y] = lighting;
+ }
+}
+
+void Ray_SetSkyBox(int slot) {
+ BITMAP *test = engine->GetSpriteGraphic(slot);
+ if (test) {
+ skybox = slot;
+ } else engine->AbortGame("Ray_SetSkybox: No such sprite!");
+}
+
+int Ray_GetSkyBox(int slot) {
+ return skybox;
+}
+
+int Ray_GetHotspotAt(int x, int y) {
+ if (!interactionmap) return -1;
+ else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1;
+ else return interactionmap [x * sWidth + y] & 0x00FF;
+}
+
+int Ray_GetObjectAt(int x, int y) {
+ if (!interactionmap) return -1;
+ else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1;
+ else return interactionmap [x * sWidth + y] >> 8;
+}
+
+FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y) {
+ float falsereturn = -1.0f;
+ if (!ZBuffer) {
+ RETURN_FLOAT(falsereturn);
+ } else if (x > sWidth || x < 0 || y > sHeight || y < 0) {
+ RETURN_FLOAT(falsereturn);
+ } else {
+
+ float zbuf = (float)ZBuffer[x][y];
+ RETURN_FLOAT(zbuf);
+ }
+}
+
+void Init_Raycaster() {
+ if (ZBuffer)
+ return;
+ //if (!worldMap) return;
+ transcolorbuffer = new unsigned char *[sWidth];
+ transalphabuffer = new unsigned char *[sWidth];
+ transslicedrawn = new bool[sWidth]();
+ transzbuffer = new double*[sWidth];
+ transwallblendmode = new int [mapWidth]();
+ ZBuffer = new double*[sWidth];
+ distTable = new double[sHeight + (sHeight >> 1)];
+ interactionmap = new short[sWidth * sHeight]();
+ for (int y = 0; y < sHeight + (sHeight >> 1); y++) {
+ distTable [y] = sHeight / (2.0 * y - sHeight);
+ }
+ for (int x = 0; x < sWidth; x++) {
+ transcolorbuffer[x] = new unsigned char [sHeight * (mapWidth)]();
+ transalphabuffer[x] = new unsigned char [sHeight * (mapWidth)]();
+ transzbuffer[x] = new double [sHeight * (mapWidth)]();
+ ZBuffer[x] = new double [sHeight]();
+ transslicedrawn [x] = false;
+ }
+}
+
+bool rendering;
+void Raycast_Render(int slot) {
+ ambientweight = 0;
+ raycastOn = true;
+ double playerrad = atan2(dirY, dirX) + (2.0 * PI);
+ rendering = true;
+ int32 w = sWidth, h = sHeight;
+ BITMAP *screen = engine->GetSpriteGraphic(slot);
+ if (!screen) engine->AbortGame("Raycast_Render: No valid sprite to draw on.");
+ engine->GetBitmapDimensions(screen, &w, &h, nullptr);
+ BITMAP *sbBm = engine->GetSpriteGraphic(skybox);
+ if (!sbBm) engine->AbortGame("Raycast_Render: No valid skybox sprite.");
+ if (skybox > 0) {
+ //int bgdeg = (int)((playerrad / PI) * 180.0) + 180;
+ int xoffset = (int)(playerrad * 320.0);
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ engine->SetVirtualScreen(screen);
+ xoffset = abs(xoffset % w);
+ if (xoffset > 0) {
+ engine->BlitBitmap(xoffset - 320, 1, sbBm, false);
+ }
+ engine->BlitBitmap(xoffset, 1, sbBm, false);
+ engine->SetVirtualScreen(virtsc);
+ }
+ int transwallcount = 0;
+ unsigned char **buffer = engine->GetRawBitmapSurface(screen);
+ for (int x = 0; x < w; x++) {
+ transslicedrawn [x] = false;
+ for (int y = 0; y < h; y++) {
+ ZBuffer[x][y] = 0;
+ }
+ }
+ //int multiplier = mapWidth;
+ memset(interactionmap, 0, sizeof(short) * (sHeight * sWidth));
+ //start the main loop
+ for (int x = 0; x < w; x++) {
+ transwallcount = 0;
+ //calculate ray position and direction
+ double cameraX = 2 * x / double(w) - 1; //x-coordinate in camera space
+ double rayPosX = posX;
+ double rayPosY = posY;
+ double rayDirX = dirX + planeX * cameraX;
+ double rayDirY = dirY + planeY * cameraX;
+
+ //which box of the map we're in
+ int mapX = int(rayPosX);
+ int mapY = int(rayPosY);
+
+ //length of ray from current position to next x or y-side
+ double sideDistX;
+ double sideDistY;
+
+ //length of ray from one x or y-side to next x or y-side
+ double deltaDistX = fsqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
+ double deltaDistY = fsqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
+ double perpWallDist = 0.0;
+
+ //what direction to step in x or y-direction (either +1 or -1)
+ int stepX;
+ int stepY;
+ int prevmapX = 0;
+ int prevmapY = 0;
+ int hit = 0; //was there a wall hit?
+ int side = 0; //was a NS or a EW wall hit?
+
+ //calculate step and initial sideDist
+ if (rayDirX < 0) {
+ stepX = -1;
+ sideDistX = (rayPosX - mapX) * deltaDistX;
+ } else {
+ stepX = 1;
+ sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
+ }
+ if (rayDirY < 0) {
+ stepY = -1;
+ sideDistY = (rayPosY - mapY) * deltaDistY;
+ } else {
+ stepY = 1;
+ sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
+ }
+ // Perform DDA
+ bool deeper = true;
+ bool opposite = true;
+ bool oppositedrawn = false;
+ double wallX = 0; // Where exactly the wall was hit
+ int drawStart;
+ int drawEnd = 0;
+ while (hit == 0 && deeper == true) {
+ if (opposite) {
+ rayDirX = -rayDirX;
+ rayDirY = -rayDirY;
+ stepX = -stepX;
+ stepY = -stepY;
+ if (sideDistX < sideDistY) side = 0;
+ else side = 1;
+ } else if (sideDistX < sideDistY) { // jump to next map square, OR in x-direction, OR in y-direction
+ sideDistX += deltaDistX;
+ mapX += stepX;
+ mapX = abs(mapX) % mapHeight;
+ side = 0;
+ if (oppositedrawn && worldMap[mapX][mapY] > 8) {
+ opposite = true;
+ oppositedrawn = false;
+ rayDirX = -rayDirX;
+ rayDirY = -rayDirY;
+ stepX = -stepX;
+ stepY = -stepY;
+ if (sideDistX < sideDistY) side = 0;
+ else side = 1;
+ } else {
+ oppositedrawn = false;
+ opposite = false;
+ }
+ } else {
+ sideDistY += deltaDistY;
+ mapY += stepY;
+ mapY = abs(mapY) % mapHeight;
+ side = 1;
+ if (oppositedrawn && worldMap[mapX][mapY] > 8) {
+ opposite = true;
+ oppositedrawn = false;
+ rayDirX = -rayDirX;
+ rayDirY = -rayDirY;
+ stepX = -stepX;
+ stepY = -stepY;
+ if (sideDistX < sideDistY) side = 0;
+ else side = 1;
+ } else {
+ oppositedrawn = false;
+ opposite = false;
+ }
+ }
+ int texside = 0;
+ if (rayDirX > 0 && side == 0) texside = 0;
+ if (rayDirX < 0 && side == 0) texside = 1;
+ if (rayDirY > 0 && side == 1) texside = 2;
+ if (rayDirY < 0 && side == 1) texside = 3;
+
+ //set this tile as seen.
+ seenMap[mapX][mapY] = 1;
+ //Check if ray has hit a wall
+ if (wallData[worldMap[mapX][mapY]].texture[texside]) {
+ bool ambientpixels = false;
+ hit = 1; //Set this to true so that by default, it's impossible to hang the engine.
+ deeper = false; //Set this to false so that we don't go deeper than we need to.
+
+ //Calculate distance of perpendicular ray (oblique distance will give fisheye effect!)
+ if (side == 0) perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
+ else perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
+ //Calculate height of line to draw on screen
+ int lineHeight = abs(int(h / perpWallDist));
+
+ //calculate lowest and highest pixel to fill in current stripe
+ drawStart = -lineHeight / 2 + h / 2;
+ if (drawStart < 0) drawStart = 0;
+ drawEnd = lineHeight / 2 + h / 2;
+ if (drawEnd >= h) drawEnd = h;
+ //texturing calculations
+ int texNum = wallData[worldMap[mapX][mapY]].texture[texside] - 1; //1 subtracted from it so that texture 0 can be used!
+ if (!opposite) {
+ //calculate value of wallX
+ if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX;
+ else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY;
+ } else {
+ if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / -rayDirY) * -rayDirX;
+ else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / -rayDirX) * -rayDirY;
+ }
+ wallX -= floor((wallX));
+
+ //x coordinate on the texture
+ int wall_light = 255;
+ int texX = int(wallX * double(texWidth));
+ if (side == 0 && rayDirX > 0) texX = texWidth - texX - 1;
+ if (side == 1 && rayDirY < 0) texX = texWidth - texX - 1;
+ bool do_ambient = false;
+ if (!opposite) {
+ if (rayDirX > 0 && side == 0) {
+ wall_light = lightMap [(int)mapX - 1 % mapWidth][(int)mapY] << 5;
+ if (ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] <= 1) do_ambient = true;
+ else if (texture[ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true;
+ }
+ if (rayDirX < 0 && side == 0) {
+ wall_light = lightMap [(int)mapX + 1 % mapWidth][(int)mapY] << 5;
+ if (ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] <= 1) do_ambient = true;
+ else if (texture[ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] - 1][(texWidth * texX) + 0] == 0) do_ambient = true;
+
+ }
+ if (rayDirY > 0 && side == 1) {
+ wall_light = lightMap [(int)mapX][(int)mapY - 1 % mapHeight] << 5;
+ if (ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] <= 1) do_ambient = true;
+ else if (texture[ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] - 1][(texWidth * 63) + texX] == 0) do_ambient = true;
+ }
+ if (rayDirY < 0 && side == 1) {
+ wall_light = lightMap [(int)mapX][(int)mapY + 1 % mapHeight] << 5;
+ if (ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] <= 1) do_ambient = true;
+ else if (texture[ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] - 1][(texWidth * 0) + 63 - texX] == 0) do_ambient = true;
+ }
+ } else if (opposite) {
+ wall_light = lightMap [(int)mapX][(int)mapY] << 5;
+ if (ceilingMap [(int)mapX][(int)mapY] <= 1) do_ambient = true;
+ if (rayDirX > 0 && side == 0) {
+ if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true;
+ }
+ if (rayDirX < 0 && side == 0) {
+ if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * texX) + 63] == 0) do_ambient = true;
+ }
+ if (rayDirY > 0 && side == 1) {
+ if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 0) + (63 - texX)] == 0) do_ambient = true;
+ }
+ if (rayDirY < 0 && side == 1) {
+ if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 63) + texX] == 0) do_ambient = true;
+ }
+ }
+ if (do_ambient) {
+ ambientpixels = true;
+ wall_light = MAX(wall_light, ambientlight);
+ }
+ wall_light = MIN(255, MAX(0, wall_light));
+ bool alphastripe = false;
+ for (int y = drawStart; y < drawEnd; y++) {
+ if (ZBuffer[x][y] > perpWallDist || ZBuffer[x][y] == 0) { //We can draw.
+ int d = y * 256 - h * 128 + lineHeight * 128; //256 and 128 factors to avoid floats
+ int texY = ((d * texHeight) / lineHeight) / 256;
+ int color = texture[texNum][texWidth * texY + texX];
+ if (color > 0) {
+ if (ambientpixels && ambientcolor) color = Mix::MixColorMultiply(ambientcolor, color, ambientcolorAmount, 1);
+ if (!wallData[worldMap[mapX][mapY]].ignorelighting[texside] && wall_light < 255) color = Mix::MixColorLightLevel(color, wall_light);
+ if (wallData[worldMap[mapX][mapY]].alpha[texside] == 255 && wallData[worldMap[mapX][mapY]].mask[texside] == 0) {
+ buffer[y][x] = color;
+ if (ambientpixels) ambientweight++;
+ //SET THE ZBUFFER FOR THE SPRITE CASTING
+ ZBuffer[x][y] = perpWallDist; //perpendicular distance is used
+ interactionmap [x * sWidth + y] = wallData[worldMap[mapX][mapY]].hotspotinteract;
+ editorMap [x][y] = ((short)mapX) << 16 | ((short)mapY);
+ } else {
+ if (transslicedrawn[x] == false) {
+ memset(transcolorbuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth));
+ memset(transalphabuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth));
+ //memset (transzbuffer[x],0,sizeof(double)*(sHeight*mapWidth));
+ transslicedrawn[x] = true;
+ }
+ transwallblendmode[transwallcount] = wallData[worldMap[mapX][mapY]].blendtype[texside];
+ int transwalloffset = transwallcount * h;
+ transcolorbuffer[x][transwalloffset + y] = color;
+ if (ambientpixels) ambientweight++;
+ if (wallData[worldMap[mapX][mapY]].mask[texside] == 0) transalphabuffer[x][transwalloffset + y] = wallData[worldMap[mapX][mapY]].alpha[texside];
+ else {
+ transalphabuffer[x][transwalloffset + y] = (wallData[worldMap[mapX][mapY]].alpha[texside] + texture[wallData[worldMap[mapX][mapY]].mask[texside]][texWidth * texY + texX]) >> 1;
+ }
+ transzbuffer[x][transwalloffset + y] = perpWallDist;
+ hit = 0;
+ deeper = true;
+ alphastripe = true;
+ }
+ } else {
+ //We found transparency, we have to draw deeper.
+ deeper = true;
+ hit = 0;
+ }
+ if ((int)mapX == selectedX && (int)mapY == selectedY) {
+ if (texX == 0 || texX == 63 || texY == 0 || texY == 63) {
+ buffer[y][x] = selectedColor;
+ ZBuffer [x][y] = perpWallDist;
+ }
+ }
+
+ }
+ }
+ if (alphastripe) {
+ if (transwallcount < mapWidth) {
+ transwallcount++;
+ }
+ alphastripe = false;
+ }
+ if (opposite) {
+ if (mapX == 0 || mapX == mapWidth || mapY == 0 || mapY == mapHeight) {
+ deeper = false;
+ hit = 0;
+ }
+ oppositedrawn = true;
+ if (deeper) opposite = false;
+ rayDirX = -rayDirX;
+ rayDirY = -rayDirY;
+ stepX = -stepX;
+ stepY = -stepY;
+ } else if (!opposite && deeper) {
+ opposite = true;
+ prevmapX = mapX;
+ prevmapY = mapY;
+ }
+ //End of wall drawing functions.
+ } else if (opposite) {
+ opposite = false;
+ //oppositedrawn = false;
+ rayDirX = -rayDirX;
+ rayDirY = -rayDirY;
+ stepX = -stepX;
+ stepY = -stepY;
+ } else if (!opposite && deeper) {
+ opposite = true;
+ prevmapX = mapX;
+ prevmapY = mapY;
+ }
+ //End of loop.
+ }
+
+ // Unused variables
+ (void)prevmapX;
+ (void)prevmapY;
+
+ //FLOOR CASTING
+
+ double floorXWall, floorYWall; //x, y position of the floor texel at the bottom of the wall
+ //4 different wall directions possible
+ if (side == 0 && rayDirX > 0) {
+ floorXWall = mapX;
+ floorYWall = mapY + wallX;
+ if (opposite) floorXWall = floorXWall + 1.0;
+ } else if (side == 0 && rayDirX < 0) {
+ floorXWall = mapX + 1.0;
+ floorYWall = mapY + wallX;
+ if (opposite) floorXWall = floorXWall - 1.0;
+ } else if (side == 1 && rayDirY > 0) {
+ floorXWall = mapX + wallX;
+ floorYWall = mapY;
+ if (opposite) floorYWall = floorYWall + 1.0;
+ } else {
+ floorXWall = mapX + wallX;
+ floorYWall = mapY + 1.0;
+ if (opposite) floorYWall = floorYWall - 1.0;
+ }
+
+ double distWall, distPlayer, currentDist;
+
+ distWall = perpWallDist;
+ distPlayer = 0.0;
+ if (drawEnd < 0)
+ drawEnd = h - 1; //becomes < 0 when the integer overflows
+ //draw the floor from drawEnd to the bottom of the screen
+ int drawdist = h;
+ int expandeddraw = h >> 1;
+ for (int y = drawEnd; y < drawdist + expandeddraw; y++) {
+ //currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead
+ currentDist = distTable[y];
+ if (y > h - 1) {
+ //if (!heightMap) break;
+ double weight = (currentDist - distPlayer) / (distWall - distPlayer);
+
+ double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
+ double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;
+
+ int floorTexX, floorTexY;
+ int cmapX = (int)currentFloorX;
+ if (cmapX > mapWidth - 1) cmapX = mapWidth - 1;
+ if (cmapX < 0) cmapX = 0;
+ int cmapY = (int)currentFloorY;
+ if (cmapY > mapHeight - 1) cmapY = mapHeight - 1;
+ if (cmapY < 0) cmapY = 0;
+ if (heightMap[cmapX][cmapY] - 1 < 1) continue;
+ int lighting = lightMap [cmapX][cmapY] << 5;
+ lighting = MIN(255, MAX(0, lighting));
+ floorTexX = int(currentFloorX * texWidth) % texWidth;
+ floorTexY = int(currentFloorY * texHeight) % texHeight;
+ int floorcolor = 0;
+ int ceilingcolor = 0;
+ int texpos = texWidth * floorTexY + floorTexX;
+ if (ceilingMap[cmapX][cmapY] - 1 > 0) {
+ ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
+ }
+ if (floorMap[cmapX][cmapY] - 1 > 0) {
+ floorcolor = texture[floorMap[cmapX][cmapY] - 1][texpos];
+ } else continue;
+ if (ceilingcolor == 0) {
+ lighting = MAX(lighting, ambientlight);
+ ambientweight ++;
+ }
+ if (lighting < 255) {
+ if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting);
+ }
+
+ if (/*heightMap &&*/ floorcolor > 0) {
+ if (heightMap[cmapX][cmapY] - 1 > 0) {
+ int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texpos] / currentDist);
+ if (raisedfloorstart > h - 1) continue;
+ if (raisedfloorstart < 0) raisedfloorstart = 0;
+ for (int ny = raisedfloorstart; ny < y; ny++) {
+ if (ny < h && (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0)) {
+ ZBuffer[x][ny] = currentDist; //perpendicular distance is used
+ buffer[ny][x] = floorcolor;
+ interactionmap [x * sWidth + ny] = 0;
+ editorMap [x][ny] = ((short)mapX) << 16 | ((short)mapY);
+ }
+ }
+ if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++;
+ }
+ }
+ } else {
+ double weight = (currentDist - distPlayer) / (distWall - distPlayer);
+
+ double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
+ double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;
+
+ int floorTexX, floorTexY;
+ int cmapX = (int)currentFloorX % mapWidth;
+ if (cmapX < 0) cmapX = 0;
+ int cmapY = (int)currentFloorY % mapHeight;
+ if (cmapY < 0) cmapY = 0;
+ int lighting = lightMap [cmapX][cmapY] << 5;
+ lighting = MIN(255, MAX(0, lighting));
+ floorTexX = int(currentFloorX * texWidth) % texWidth;
+ floorTexY = int(currentFloorY * texHeight) % texHeight;
+ int floorcolor = 0;
+ int ceilingcolor = 0;
+ if (floorMap[cmapX][cmapY] - 1 > 0) {
+ floorcolor = texture[floorMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
+ }
+ if (ceilingMap[cmapX][cmapY] - 1 > 0) {
+ ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX];
+ }
+ if (ceilingcolor == 0) {
+ lighting = MAX(lighting, ambientlight);
+ ambientweight++;
+ }
+ if (lighting < 255) {
+ if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting);
+ if (ceilingcolor) ceilingcolor = Mix::MixColorLightLevel(ceilingcolor, lighting);
+ }
+
+ if (/*heightMap &&*/ floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) {
+ if (heightMap[cmapX][cmapY] - 1 > 0) {
+ int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX] / currentDist);
+ if (raisedfloorstart > h - 1) continue;
+ if (raisedfloorstart < 0) raisedfloorstart = 0;
+ for (int ny = raisedfloorstart; ny < y; ny++) {
+ if (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0) {
+ ZBuffer[x][ny] = currentDist; //perpendicular distance is used
+ buffer[ny][x] = floorcolor;
+ interactionmap [x * sWidth + ny] = 0;
+ editorMap [x][ny] = ((short)cmapX) << 16 | ((short)cmapY);
+ }
+ }
+ if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++;
+ }
+ }
+ //floor
+ //ceiling (symmetrical!)
+ //SET THE ZBUFFER FOR THE SPRITE CASTING
+ if (floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) {
+ ZBuffer[x][y] = currentDist; //perpendicular distance is used
+ buffer[y][x] = floorcolor;
+ editorMap [x][y] = ((short)cmapX) << 16 | ((short)cmapY);
+ } else ZBuffer[x][y] = 9999999999999.0;
+ if (currentDist < ZBuffer[x][h - y] || ZBuffer[x][h - y] == 0) {
+ if (ceilingcolor > 0) {
+ ZBuffer[x][h - y] = currentDist; //perpendicular distance is used
+ buffer[h - y][x] = ceilingcolor;
+ } else ZBuffer[x][h - y] = 999999999999.0;
+ editorMap [x][h - y] = ((short)cmapX) << 16 | ((short)cmapY);
+ }
+ interactionmap [x * sWidth + y] = 0;
+ interactionmap [x * sWidth + (h - y)] = 0;
+ if ((int)cmapX == selectedX && (int)cmapY == selectedY) {
+ if (floorTexX == 0 || floorTexX == 63 || floorTexY == 0 || floorTexY == 63) {
+ buffer[y][x] = selectedColor;
+ ZBuffer [x][y] = perpWallDist;
+ buffer[h - y][x] = selectedColor;
+ ZBuffer [x][h - y] = perpWallDist;
+ }
+ }
+
+
+ }
+ }
+ //TRANSLUCENT WALL RENDERING
+ if (transslicedrawn[x] == true) {
+ for (int y = 0; y < h; y++) {
+ for (int transwalldrawn = 0; transwalldrawn < transwallcount; transwalldrawn++) {
+ int transwalloffset = transwalldrawn * h;
+ int color = transcolorbuffer[x][transwalloffset + y];
+ if (color != 0) {
+ if (transwallblendmode[transwalldrawn] == 0) buffer[y][x] = Mix::MixColorAlpha(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]); //paint pixel if it isn't black, black is the invisible color
+ else if (transwallblendmode[transwalldrawn] == 1) buffer[y][x] = Mix::MixColorAdditive(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]);
+ //if (ZBuffer[x][y] > transzbuffer[transwalldrawn*h+y]) ZBuffer[x][y] = transzbuffer[transwalldrawn*h+y]; //put the sprite on the zbuffer so we can draw around it.
+ }
+ }
+ }
+ }
+ //End of wall loop.
+ }
+
+
+ //SPRITE CASTING
+ //sort sprites from far to close
+
+ //Initialize Sprites for casting.
+ double invDet = 1.0 / (planeX * dirY - dirX * planeY);
+ for (int i = 0; i < numSprites; i++) {
+ spriteOrder[i] = i;
+ spriteTransformY[i] = ((posX - sprite[i].x) * (posX - sprite[i].x) + (posY - sprite[i].y) * (posY - sprite[i].y));
+ }
+ combSort(spriteOrder, spriteTransformY, numSprites);
+ for (int i = 0; i < numSprites; i++) {
+ double spriteX = sprite[spriteOrder[i]].x - posX;
+ double spriteY = sprite[spriteOrder[i]].y - posY;
+ spriteTransformX[i] = invDet * (dirY * spriteX - dirX * spriteY);
+ spriteTransformY[i] = invDet * (-planeY * spriteX + planeX * spriteY);
+ }
+
+ int transwalldraw = 0;
+ //after sorting the sprites, do the projection and draw them
+ for (int i = 0; i < numSprites; i++) {
+ int flipped = 0;
+ if (sprite[spriteOrder[i]].view != 0) {
+
+ double sprrad = atan2(sprite[spriteOrder[i]].y - posY, sprite[spriteOrder[i]].x - posX);
+ int sprdeg = (int)(sprrad / 3.1415 * 180.0);
+ sprdeg = ((sprdeg + 180) + sprite[spriteOrder[i]].angle) % 360;
+ int loop = 0;
+ if (sprdeg > 336 || sprdeg < 23) loop = 0;
+ else if (sprdeg > 22 && sprdeg < 68) loop = 6;
+ else if (sprdeg > 67 && sprdeg < 113) loop = 1;
+ else if (sprdeg > 112 && sprdeg < 158) loop = 7;
+ else if (sprdeg > 157 && sprdeg < 203) loop = 3;
+ else if (sprdeg > 202 && sprdeg < 248) loop = 5;
+ else if (sprdeg > 247 && sprdeg < 293) loop = 2;
+ else if (sprdeg > 292 && sprdeg < 337) loop = 4;
+ AGSViewFrame *vf = engine->GetViewFrame(sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame);
+ if (vf == nullptr) engine->AbortGame("Raycast_Render: Unable to load viewframe of sprite.");
+ else {
+ sprite[spriteOrder[i]].texture = vf->pic;
+ int (*sfGetGameParameter)(int, int, int, int);
+ sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
+ flipped = sfGetGameParameter(13, sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame);
+ }
+ }
+ //translate sprite position to relative to camera
+ //double spriteX = sprite[spriteOrder[i]].x - posX;
+ //double spriteY = sprite[spriteOrder[i]].y - posY;
+
+ //transform sprite with the inverse camera matrix
+ // [ planeX dirX ] -1 [ dirY -dirX ]
+ // [ ] = 1/(planeX*dirY-dirX*planeY) * [ ]
+ // [ planeY dirY ] [ -planeY planeX ]
+
+ //double invDet = 1.0 / (planeX * dirY - dirX * planeY); //required for correct matrix multiplication
+ //double spriteX = sprite[spriteOrder[i]].x - posX;
+ //double spriteY = sprite[spriteOrder[i]].y - posY;
+ //double transformX = invDet * (dirY * spriteX - dirX * spriteY);
+ //double transformY = invDet * (-planeY * spriteX + planeX * spriteY); //this is actually the depth inside the screen, that what Z is in 3D
+
+ int spriteScreenX = int((w / 2) * (1 + spriteTransformX[i] / spriteTransformY[i]));
+
+ //parameters for scaling and moving the sprites
+ BITMAP *spritetexbm = engine->GetSpriteGraphic(sprite[spriteOrder[i]].texture);
+ unsigned char **spritetex = engine->GetRawBitmapSurface(spritetexbm);
+ int sprw = engine->GetSpriteWidth(sprite[spriteOrder[i]].texture);
+ int sprh = engine->GetSpriteHeight(sprite[spriteOrder[i]].texture);
+
+ double uDiv = ((double)sprw / (double)texWidth) + sprite[spriteOrder[i]].uDivW;
+ double vDiv = ((double)sprh / (double)texHeight) + sprite[spriteOrder[i]].uDivH;
+ double vMove = sprite[spriteOrder[i]].vMove + ((double)texHeight - (double)sprh) * 1.6;
+ double hMove = sprite[spriteOrder[i]].hMove;
+ int vMoveScreen = int(vMove / spriteTransformY[i]);
+ int hMoveScreen = int(hMove / spriteTransformY[i]);
+ //calculate height of the sprite on screen
+ int spriteHeight = abs(int(h / (spriteTransformY[i]) * vDiv)) ; //using "transformY" instead of the real distance prevents fisheye
+ //calculate lowest and highest pixel to fill in current stripe
+ int drawStartY = -spriteHeight / 2 + h / 2 + vMoveScreen;
+ if (drawStartY < 0) drawStartY = 0;
+ int drawEndY = spriteHeight / 2 + h / 2 + vMoveScreen;
+ if (drawEndY >= h) drawEndY = h - 1;
+
+ //calculate width of the sprite
+ int spriteWidth = abs(int (h / (spriteTransformY[i]) * uDiv)) ;
+ int drawStartX = -spriteWidth / 2 + spriteScreenX + hMoveScreen;
+ if (drawStartX < 0) drawStartX = 0;
+ int drawEndX = spriteWidth / 2 + spriteScreenX + hMoveScreen;
+ if (drawEndX >= w) drawEndX = w - 1;
+ int spr_light = lightMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] << 5;
+ spr_light = MIN(255, MAX(0, spr_light));
+ int floorTexX = int(sprite[spriteOrder[i]].x * texWidth) % texWidth;
+ int floorTexY = int(sprite[spriteOrder[i]].y * texHeight) % texHeight;
+ if (ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] == 0) {
+ spr_light = MAX(spr_light, ambientlight);
+ } else if (texture[ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] - 1][texWidth * floorTexY + floorTexX] == 0) spr_light = MAX(spr_light, ambientlight);
+ //loop through every vertical stripe of the sprite on screen
+
+
+ for (int stripe = drawStartX; stripe < drawEndX; stripe++) {
+ transwalldraw = 0;
+ //int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * texWidth / spriteWidth) / 256;
+ int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * sprw / spriteWidth) / 256;
+ if (texX >= sprw || texX < 0) continue;
+ if (flipped) texX = sprw - texX;
+ //the conditions in the if are:
+ //1) it's in front of camera plane so you don't see things behind you
+ //2) it's on the screen (left)
+ //3) it's on the screen (right)
+ //4) ZBuffer, with perpendicular distance
+ if (spriteTransformY[i] > 0 && stripe > 0 && stripe < w)
+ for (int y = drawStartY; y < drawEndY; y++) { //for every pixel of the current stripe
+ if (spriteTransformY[i] < ZBuffer[stripe][y]) {
+ if (transslicedrawn[stripe]) while ((transzbuffer[stripe][transwalldraw * h + y] > spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0) && (transwalldraw < transwallcount)) transwalldraw++;
+ int d = (y - vMoveScreen) * 256 - h * 128 + spriteHeight * 128; //256 and 128 factors to avoid floats
+ //int texY = ((d * texHeight) / spriteHeight) / 256;
+ int texY = ((d * sprh) / spriteHeight) / 256;
+ if (texY >= sprh || texY < 0) continue;
+ //unsigned char color = texture[sprite[spriteOrder[i]].texture][texWidth * texY + texX]; //get current color from the texture
+ unsigned char color = spritetex[texY][texX]; //get current color from the texture
+ if (color != 0) {
+ if (sprite[spriteOrder[i]].alpha < 255) {
+ if (sprite[spriteOrder[i]].blendmode == 0) color = Mix::MixColorAlpha(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha);
+ if (sprite[spriteOrder[i]].blendmode == 1) color = Mix::MixColorAdditive(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha);
+ }
+ color = Mix::MixColorLightLevel(color, spr_light);
+ if (transzbuffer[stripe][transwalldraw * h + y] < spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0 && transslicedrawn[stripe] && transcolorbuffer[stripe][transwalldraw * h + y] > 0 && transalphabuffer[stripe][transwalldraw * h + y] > 0) {
+ if (transwallblendmode[transwalldraw] == 0) color = Mix::MixColorAlpha(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]);
+ else if (transwallblendmode[transwalldraw] == 1) color = Mix::MixColorAdditive(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]);
+ buffer[y][stripe] = color;
+ ZBuffer[stripe][y] = transzbuffer[stripe][transwalldraw * h + y];
+ } else {
+ buffer[y][stripe] = color; //paint pixel if it isn't black, black is the invisible color
+ ZBuffer[stripe][y] = spriteTransformY[i]; //put the sprite on the zbuffer so we can draw around it.
+ }
+ interactionmap [stripe * sWidth + y] = sprite[spriteOrder[i]].objectinteract << 8;
+ }
+ }
+ }
+ }
+ engine->ReleaseBitmapSurface(spritetexbm);
+ }
+ engine->ReleaseBitmapSurface(screen);
+ engine->NotifySpriteUpdated(slot);
+ rendering = false;
+
+}
+
+void QuitCleanup() {
+ if (!rendering) {
+ for (int i = 0; i < sWidth; ++i) {
+ if (transcolorbuffer[i])delete [] transcolorbuffer[i];
+ if (transalphabuffer[i])delete [] transalphabuffer[i];
+ if (transzbuffer[i])delete [] transzbuffer[i];
+ if (ZBuffer[i]) delete [] ZBuffer[i];
+ }
+ if (transcolorbuffer) delete [] transcolorbuffer;
+ if (transalphabuffer) delete [] transalphabuffer;
+ if (transzbuffer) delete [] transzbuffer;
+ if (ZBuffer) delete [] ZBuffer;
+ if (transwallblendmode) delete [] transwallblendmode;
+ if (interactionmap) delete [] interactionmap;
+ }
+}
+
+void MoveForward() {
+ double newposx = 0;
+ if (dirX > 0) newposx = 0.1 + posX + dirX * moveSpeed;
+ else newposx = -0.1 + posX + dirX * moveSpeed;
+ int texsidex = 0;
+ int inside_texsidex = 0;
+ double newposy = 0;
+ if (dirY > 0) newposy = 0.1 + posY + dirY * moveSpeed;
+ else newposy = -0.1 + posY + dirY * moveSpeed;
+ int texsidey = 0;
+ int inside_texsidey = 0;
+ bool inside = false;
+ if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true;
+ if (dirX > 0 && !inside) {
+ texsidex = 0;
+ inside_texsidex = 1;
+ } else if (dirX > 0) {
+ texsidex = 1;
+ inside_texsidex = 0;
+ }
+ if (dirX < 0 && !inside) {
+ texsidex = 1;
+ inside_texsidex = 0;
+ } else if (dirX < 0) {
+ texsidex = 0;
+ inside_texsidex = 1;
+ }
+
+ if (dirY > 0 && !inside) {
+ texsidey = 2;
+ inside_texsidey = 3;
+ } else if (dirY > 0) {
+ texsidey = 3;
+ inside_texsidey = 2;
+ }
+ if (dirY < 0 && !inside) {
+ texsidey = 3;
+ inside_texsidey = 2;
+ } else if (dirY < 0) {
+ texsidey = 2;
+ inside_texsidey = 3;
+ }
+
+ if (!noclip && !inside) {
+ if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed;
+ if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed;
+ } else if (!noclip && inside) {
+ posX += dirX * moveSpeed;
+ posY += dirY * moveSpeed;
+ } else {
+ if (int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed;
+ if (int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed;
+ }
+}
+
+void MoveBackward() {
+ double newposx = 0;
+ if (dirX > 0) newposx = -0.1 + posX - dirX * moveSpeed;
+ else newposx = 0.1 + posX - dirX * moveSpeed;
+ int texsidex = 0;
+ int inside_texsidex = 0;
+ double newposy = 0;
+ if (dirY > 0) newposy = -0.1 + posY - dirY * moveSpeed;
+ else newposy = 0.1 + posY - dirY * moveSpeed;
+ int texsidey = 0;
+ int inside_texsidey = 0;
+ bool inside = false;
+ if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true;
+ if (dirX > 0 && !inside) {
+ texsidex = 1;
+ inside_texsidex = 0;
+ } else if (dirX > 0) {
+ texsidex = 0;
+ inside_texsidex = 1;
+ }
+ if (dirX < 0 && !inside) {
+ texsidex = 0;
+ inside_texsidex = 1;
+ } else if (dirX < 0) {
+ texsidex = 1;
+ inside_texsidex = 0;
+ }
+
+ if (dirY > 0 && !inside) {
+ texsidey = 3;
+ inside_texsidey = 2;
+ } else if (dirY > 0) {
+ texsidey = 2;
+ inside_texsidey = 3;
+ }
+ if (dirY < 0 && !inside) {
+ texsidey = 2;
+ inside_texsidey = 3;
+ } else if (dirY < 0) {
+ texsidey = 3;
+ inside_texsidey = 2;
+ }
+
+ if ((int)posX == (int)newposy && (int)posY == (int)newposy) inside = true;
+ if (!noclip && !inside) {
+ if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed;
+ if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed;
+ } else if (!noclip && inside) {
+ posX -= dirX * moveSpeed;
+ posY -= dirY * moveSpeed;
+ } else {
+ if (int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed;
+ if (int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed;
+ }
+}
+
+
+
+/*
+void MoveBackward ()
+{
+ double newposx;
+ if (dirX > 0) newposx = -0.2 + posX - dirX * moveSpeed;
+ else newposx = 0.2 + posX - dirX * moveSpeed;
+ double newposy;
+ if (dirY > 0) newposy = -0.2 + posY - dirY * moveSpeed;
+ else newposy = 0.2 + posY - dirY * moveSpeed;
+ if(worldMap[int(newposx)][int(posY)] == false || worldMap[int(newposx)][int(posY)] > 8) posX -= dirX * moveSpeed;
+ if(worldMap[int(posX)][int(newposy)] == false || worldMap[int(posX)][int(newposy)] > 8) posY -= dirY * moveSpeed;
+}
+*/
+
+void RotateLeft() {
+ double oldDirX = dirX;
+ dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed);
+ dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed);
+ double oldPlaneX = planeX;
+ planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);
+ planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
+}
+
+void RotateRight() {
+ double oldDirX = dirX;
+ dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed);
+ dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed);
+ double oldPlaneX = planeX;
+ planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
+ planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
+}
+
+//sort algorithm
+void combSort(int *order, double *dist, int amount) {
+ int gap = amount;
+ bool swapped = false;
+ while (gap > 1 || swapped) {
+ //shrink factor 1.3
+ gap = (gap * 10) / 13;
+ if (gap == 9 || gap == 10) gap = 11;
+ if (gap < 1) gap = 1;
+ swapped = false;
+ for (int i = 0; i < amount - gap; i++) {
+ int j = i + gap;
+ if (dist[i] < dist[j]) {
+ SWAP(dist[i], dist[j]);
+ SWAP(order[i], order[j]);
+ swapped = true;
+ }
+ }
+ }
+}
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
+
diff --git a/engines/ags/plugins/ags_pal_render/raycast.h b/engines/ags/plugins/ags_pal_render/raycast.h
index 3e797a37e3..f12947968f 100644
--- a/engines/ags/plugins/ags_pal_render/raycast.h
+++ b/engines/ags/plugins/ags_pal_render/raycast.h
@@ -1,211 +1,211 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H
-#define AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H
-
-#include "ags/plugins/ags_pal_render/pal_render.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define mapWidth 64
-#define mapHeight 64
-
-struct Sprite {
- double x;
- double y;
- int texture;
- unsigned char alpha;
- int blendmode;
- double uDivW;
- double uDivH;
- double vMove;
- double hMove;
- char objectinteract;
- int view;
- int frame;
- int angle;
-};
-
-struct wallType {
- int texture[4];
- int solid[4];
- int ignorelighting[4];
- int alpha[4];
- int blendtype[4];
- int mask[4];
- unsigned char hotspotinteract;
-};
-
-
-extern bool raycastOn;
-extern double posX;
-extern double posY; //x and y start position
-extern double dirX;
-extern double dirY; //initial direction vector
-extern double planeX;
-extern double planeY; //the 2d raycaster version of camera plane
-extern double moveSpeed; //the constant value is in squares/second
-extern double rotSpeed; //the constant value is in radians/second
-extern unsigned char worldMap[64][64];
-extern unsigned char lightMap[64][64];
-extern int ceilingMap[64][64];
-extern int floorMap[64][64];
-extern int heightMap[64][64];
-extern unsigned char seenMap[64][64];
-//extern int mapWidth;
-//extern int mapHeight;
-extern int textureSlot;
-extern int ambientlight;
-
-#define numSprites 256
-extern Sprite sprite[numSprites];
-
-
-#define texWidth 64
-#define texHeight 64
-#define MAX_TEXTURES 512
-extern unsigned char texture[][texWidth * texHeight];
-
-extern bool heightmapOn;
-
-
-extern wallType wallData[256];
-
-//arrays used to sort the sprites
-extern unsigned char **transcolorbuffer;
-extern unsigned char **transalphabuffer;
-extern double **transzbuffer;
-extern bool *transslicedrawn;
-extern int *transwallblendmode;
-extern double **ZBuffer;
-extern double *distTable;
-extern short *interactionmap;
-extern int skybox;
-
-
-
-void MakeTextures(int slot);
-void Raycast_Render(int slot);
-void MoveForward();
-void MoveBackward();
-void RotateLeft();
-void RotateRight();
-void Init_Raycaster();
-void QuitCleanup();
-void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot);
-void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove));
-void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y));
-FLOAT_RETURN_TYPE Ray_GetPlayerX();
-FLOAT_RETURN_TYPE Ray_GetPlayerY();
-int Ray_GetPlayerAngle();
-void Ray_SetPlayerAngle(int angle);
-
-int Ray_GetWallHotspot(int id);
-int Ray_GetWallTexture(int id, int dir);
-int Ray_GetWallSolid(int id, int dir);
-int Ray_GetWallIgnoreLighting(int id, int dir);
-int Ray_GetWallAlpha(int id, int dir);
-int Ray_GetWallBlendType(int id, int dir);
-
-void Ray_SelectTile(int x, int y, unsigned char color);
-
-int Ray_GetHotspotAt(int x, int y);
-int Ray_GetObjectAt(int x, int y);
-
-void Ray_DrawTile(int spr, int tile);
-void Ray_DrawOntoTile(int spr, int tile);
-void Ray_SetNoClip(int value);
-int Ray_GetNoClip();
-void Ray_SetSpriteInteractObj(int id, int obj);
-int Ray_GetSpriteInteractObj(int id);
-void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y));
-void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove));
-FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id);
-FLOAT_RETURN_TYPE Ray_GetSpriteX(int id);
-FLOAT_RETURN_TYPE Ray_GetSpriteY(int id);
-
-void Ray_SetWallHotspot(int id, char hotsp);
-void Ray_SetWallTextures(int id, int n, int s, int w, int e);
-void Ray_SetWallSolid(int id, int n, int s, int w, int e);
-void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e);
-void Ray_SetWallAlpha(int id, int n, int s, int w, int e);
-void Ray_SetWallBlendType(int id, int n, int s, int w, int e);
-
-FLOAT_RETURN_TYPE Ray_GetMoveSpeed();
-void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed));
-FLOAT_RETURN_TYPE Ray_GetRotSpeed();
-void Ray_SetRotSpeed(SCRIPT_FLOAT(speed));
-int Ray_GetWallAt(int x, int y);
-int Ray_GetLightAt(int x, int y);
-void Ray_SetLightAt(int x, int y, int light);
-void Ray_SetWallAt(int x, int y, int id);
-void Ray_SetPlaneY(SCRIPT_FLOAT(y));
-FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y);
-int Ray_GetSpriteAngle(int id);
-void Ray_SetSpriteAngle(int id, int angle);
-void Ray_SetSpriteView(int id, int view);
-int Ray_GetSpriteView(int id);
-void Ray_SetSpriteFrame(int id, int frame);
-int Ray_GetSpriteFrame(int id);
-
-int Ray_GetTileX_At(int x, int y);
-int Ray_GetTileY_At(int x, int y);
-
-void Ray_SetSkyBox(int slot);
-int Ray_GetSkyBox(int slot);
-
-void Ray_SetAmbientLight(int value);
-int Ray_GetAmbientLight();
-void Ray_SetAmbientColor(int color, int amount);
-
-
-int Ray_GetSpriteAlpha(int id);
-void Ray_SetSpriteAlpha(int id, int alpha);
-int Ray_GetSpritePic(int id);
-void Ray_SetSpritePic(int id, int slot);
-
-FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id);
-void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale));
-FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id);
-void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale));
-
-void Ray_SetSpriteBlendType(int id, int type);
-int Ray_GetSpriteBlendType(int id);
-
-void Ray_SetFloorAt(int x, int y, int tex);
-void Ray_SetCeilingAt(int x, int y, int tex);
-int Ray_GetCeilingAt(int x, int y);
-int Ray_GetFloorAt(int x, int y);
-int Ray_GetLightingAt(int x, int y);
-void Ray_SetLightingAt(int x, int y, unsigned char lighting);
-int Ray_GetAmbientWeight();
-
-int Ray_HasSeenTile(int x, int y);
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H
+#define AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H
+
+#include "ags/plugins/ags_pal_render/pal_render.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define mapWidth 64
+#define mapHeight 64
+
+struct Sprite {
+ double x;
+ double y;
+ int texture;
+ unsigned char alpha;
+ int blendmode;
+ double uDivW;
+ double uDivH;
+ double vMove;
+ double hMove;
+ char objectinteract;
+ int view;
+ int frame;
+ int angle;
+};
+
+struct wallType {
+ int texture[4];
+ int solid[4];
+ int ignorelighting[4];
+ int alpha[4];
+ int blendtype[4];
+ int mask[4];
+ unsigned char hotspotinteract;
+};
+
+
+extern bool raycastOn;
+extern double posX;
+extern double posY; //x and y start position
+extern double dirX;
+extern double dirY; //initial direction vector
+extern double planeX;
+extern double planeY; //the 2d raycaster version of camera plane
+extern double moveSpeed; //the constant value is in squares/second
+extern double rotSpeed; //the constant value is in radians/second
+extern unsigned char worldMap[64][64];
+extern unsigned char lightMap[64][64];
+extern int ceilingMap[64][64];
+extern int floorMap[64][64];
+extern int heightMap[64][64];
+extern unsigned char seenMap[64][64];
+//extern int mapWidth;
+//extern int mapHeight;
+extern int textureSlot;
+extern int ambientlight;
+
+#define numSprites 256
+extern Sprite sprite[numSprites];
+
+
+#define texWidth 64
+#define texHeight 64
+#define MAX_TEXTURES 512
+extern unsigned char texture[][texWidth * texHeight];
+
+extern bool heightmapOn;
+
+
+extern wallType wallData[256];
+
+//arrays used to sort the sprites
+extern unsigned char **transcolorbuffer;
+extern unsigned char **transalphabuffer;
+extern double **transzbuffer;
+extern bool *transslicedrawn;
+extern int *transwallblendmode;
+extern double **ZBuffer;
+extern double *distTable;
+extern short *interactionmap;
+extern int skybox;
+
+
+
+void MakeTextures(int slot);
+void Raycast_Render(int slot);
+void MoveForward();
+void MoveBackward();
+void RotateLeft();
+void RotateRight();
+void Init_Raycaster();
+void QuitCleanup();
+void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot);
+void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove));
+void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y));
+FLOAT_RETURN_TYPE Ray_GetPlayerX();
+FLOAT_RETURN_TYPE Ray_GetPlayerY();
+int Ray_GetPlayerAngle();
+void Ray_SetPlayerAngle(int angle);
+
+int Ray_GetWallHotspot(int id);
+int Ray_GetWallTexture(int id, int dir);
+int Ray_GetWallSolid(int id, int dir);
+int Ray_GetWallIgnoreLighting(int id, int dir);
+int Ray_GetWallAlpha(int id, int dir);
+int Ray_GetWallBlendType(int id, int dir);
+
+void Ray_SelectTile(int x, int y, unsigned char color);
+
+int Ray_GetHotspotAt(int x, int y);
+int Ray_GetObjectAt(int x, int y);
+
+void Ray_DrawTile(int spr, int tile);
+void Ray_DrawOntoTile(int spr, int tile);
+void Ray_SetNoClip(int value);
+int Ray_GetNoClip();
+void Ray_SetSpriteInteractObj(int id, int obj);
+int Ray_GetSpriteInteractObj(int id);
+void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y));
+void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove));
+FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id);
+FLOAT_RETURN_TYPE Ray_GetSpriteX(int id);
+FLOAT_RETURN_TYPE Ray_GetSpriteY(int id);
+
+void Ray_SetWallHotspot(int id, char hotsp);
+void Ray_SetWallTextures(int id, int n, int s, int w, int e);
+void Ray_SetWallSolid(int id, int n, int s, int w, int e);
+void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e);
+void Ray_SetWallAlpha(int id, int n, int s, int w, int e);
+void Ray_SetWallBlendType(int id, int n, int s, int w, int e);
+
+FLOAT_RETURN_TYPE Ray_GetMoveSpeed();
+void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed));
+FLOAT_RETURN_TYPE Ray_GetRotSpeed();
+void Ray_SetRotSpeed(SCRIPT_FLOAT(speed));
+int Ray_GetWallAt(int x, int y);
+int Ray_GetLightAt(int x, int y);
+void Ray_SetLightAt(int x, int y, int light);
+void Ray_SetWallAt(int x, int y, int id);
+void Ray_SetPlaneY(SCRIPT_FLOAT(y));
+FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y);
+int Ray_GetSpriteAngle(int id);
+void Ray_SetSpriteAngle(int id, int angle);
+void Ray_SetSpriteView(int id, int view);
+int Ray_GetSpriteView(int id);
+void Ray_SetSpriteFrame(int id, int frame);
+int Ray_GetSpriteFrame(int id);
+
+int Ray_GetTileX_At(int x, int y);
+int Ray_GetTileY_At(int x, int y);
+
+void Ray_SetSkyBox(int slot);
+int Ray_GetSkyBox(int slot);
+
+void Ray_SetAmbientLight(int value);
+int Ray_GetAmbientLight();
+void Ray_SetAmbientColor(int color, int amount);
+
+
+int Ray_GetSpriteAlpha(int id);
+void Ray_SetSpriteAlpha(int id, int alpha);
+int Ray_GetSpritePic(int id);
+void Ray_SetSpritePic(int id, int slot);
+
+FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id);
+void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale));
+FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id);
+void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale));
+
+void Ray_SetSpriteBlendType(int id, int type);
+int Ray_GetSpriteBlendType(int id);
+
+void Ray_SetFloorAt(int x, int y, int tex);
+void Ray_SetCeilingAt(int x, int y, int tex);
+int Ray_GetCeilingAt(int x, int y);
+int Ray_GetFloorAt(int x, int y);
+int Ray_GetLightingAt(int x, int y);
+void Ray_SetLightingAt(int x, int y, unsigned char lighting);
+int Ray_GetAmbientWeight();
+
+int Ray_HasSeenTile(int x, int y);
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
+
+#endif
Commit: bfe16d0ed420992d2c9d42bedb0edeb8f483260e
https://github.com/scummvm/scummvm/commit/bfe16d0ed420992d2c9d42bedb0edeb8f483260e
Author: Ori Avtalion (ori at avtalion.name)
Date: 2021-02-11T20:31:17+02:00
Commit Message:
AGS: Silence clang warnings
Changed paths:
engines/ags/engine/script/cc_instance.cpp
engines/ags/game_scanner.cpp
engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
engines/ags/plugins/ags_pal_render/pal_render.h
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index cab7c8f729..6a2a70a7cd 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -252,15 +252,13 @@ ccInstance *ccInstance::Fork() {
}
void ccInstance::Abort() {
- if ((this != nullptr) && (pc != 0))
+ if (pc != 0)
flags |= INSTF_ABORTED;
}
void ccInstance::AbortAndDestroy() {
- if (this != nullptr) {
- Abort();
- flags |= INSTF_FREE;
- }
+ Abort();
+ flags |= INSTF_FREE;
}
#define ASSERT_STACK_SPACE_AVAILABLE(N) \
diff --git a/engines/ags/game_scanner.cpp b/engines/ags/game_scanner.cpp
index 0d4ccc69d5..ef19dcbba5 100644
--- a/engines/ags/game_scanner.cpp
+++ b/engines/ags/game_scanner.cpp
@@ -51,10 +51,10 @@ void GameScanner::scan(const Common::String &startFolder) {
if (!_oldGames.empty()) {
debug("// Pre 2.5 games that aren't supported");
for (EntryArray::iterator it = _oldGames.begin(); it != _oldGames.end(); ++it) {
- debug("UNSUPPORTED_ENTRY(\"\", \"%s\", \"%s\", %u),",
+ debug("UNSUPPORTED_ENTRY(\"\", \"%s\", \"%s\", %lu),",
it->_filename.c_str(), it->_md5.c_str(), it->_filesize);
}
- debug("");
+ debugN("\n");
}
debug("// 2.5+ games that should be supported");
@@ -64,14 +64,14 @@ void GameScanner::scan(const Common::String &startFolder) {
debug("{ \"%s\", \"%s\" },", it->_id.c_str(), it->_gameName.c_str());
gameDescs[it->_id] = true;
}
- debug("");
+ debugN("\n");
for (EntryArray::iterator it = _games.begin(); it != _games.end(); ++it) {
- debug("ENGLISH_ENTRY(\"%s\", \"%s\", \"%s\", %u),",
+ debug("ENGLISH_ENTRY(\"%s\", \"%s\", \"%s\", %lu),",
it->_id.c_str(), it->_filename.c_str(),
it->_md5.c_str(), it->_filesize);
}
- debug("");
+ debugN("\n");
}
void GameScanner::scanFolder(const Common::FSNode &folder) {
diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
index 6680a187d9..99316a3bd0 100644
--- a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
+++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp
@@ -1,1849 +1,1849 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "ags/lib/allegro.h"
-#include "ags/plugins/ags_pal_render/ags_pal_render.h"
-#include "ags/plugins/ags_pal_render/pal_render.h"
-#include "ags/plugins/ags_pal_render/raycast.h"
-#include "ags/ags.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define MAX_OVERLAYS 128
-#define MAX_STARS 1024
-#define MAX_DEPTH 64
-
-#define PI (3.1415926535f)
-#define HALF_PI (0.5f * PI)
-#define TWO_PI (2.0f * PI)
-#define TWO_PI_INV (1.0f / TWO_PI)
-
-const float halfpi = (0.5f * PI);
-const float twopi = (2.0f * PI);
-const float twopi_inv = (1.0f / TWO_PI);
-const float pisquared = PI * PI;
-const float picubed = PI * PI * PI;
-
-IAGSEngine *engine;
-
-//unsigned char clut[256][256];
-unsigned char clut[65536];
-
-struct transoverlaytype {
- int sprite;
- int spritemask;
- int blendtype;
- int x;
- int y;
- int trans;
- int level;
- bool enabled;
-} overlay[MAX_OVERLAYS];
-
-int clutslot;
-int drawreflections;
-unsigned char cycle_remap [256];
-
-struct starstype {
- float x;
- float y;
- float z;
- unsigned char color;
- long sprite;
- int maxrad;
- int scaleboost;
-};
-starstype *stars;
-
-struct starsoptions {
- float speed;
- int maxstars;
- int depthmultiplier;
- int originx;
- int originy;
- int overscan;
-} Starfield;
-long *reflectionmap;
-BITMAP *rcolormap;
-BITMAP *ralphamap;
-
-struct charrefopt {
- char reflect;
- int replaceview;
-};
-
-struct objrefopt {
- char reflect;
- char ignorescaling;
-};
-
-struct reflectionopt {
- charrefopt *Characters;
- objrefopt *Objects;
- int blendslot;
- int blendamount;
-} Reflection;
-
-int dummy;
-
-#define LENS_WIDTH 150
-
-struct LensDistort {
- int xoffset;
- int yoffset;
-};
-
-LensDistort *lens;
-struct LensOpt {
- bool draw;
- int lenswidth;
- int lenszoom;
- int level;
- int x;
- int y;
- int clampoffset;
-} LensOption;
-
-const int alphamultiply [4096] = {
-//#include "alphamultiply.txt"
-};
-float rot_sine_LUT[360];
-float rot_cos_LUT[360];
-
-BITMAP *backgroundimage;
-
-PALSTRUCT objectivepal[256];
-int bgimgspr;
-
-void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) {
- objectivepal[index].r = r;
- objectivepal[index].b = b;
- objectivepal[index].g = g;
-}
-
-int ReadObjectivePaletteR(unsigned char index) {
- return objectivepal[index].r;
-}
-
-int ReadObjectivePaletteB(unsigned char index) {
- return objectivepal[index].b;
-}
-int ReadObjectivePaletteG(unsigned char index) {
- return objectivepal[index].g;
-}
-
-
-#define SQRT_MAGIC_F 0x5f3759df
-float q3sqrt(const float x) {
- const float xhalf = 0.5f * x;
-
- union { // get bits for floating value
- float x;
- int i;
- } u;
- u.x = x;
- u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
- return x * u.x * (1.5f - xhalf * u.x * u.x); // Newton step, repeating increases accuracy
-}
-
-void Make_Sin_Lut() {
- for (int angle = 0; angle < 360; angle++) {
- double rad = (angle * PI) / 180.0;
- rot_sine_LUT [angle] = static_cast<float>(sin(rad));
- rot_cos_LUT [angle] = static_cast<float>(cos(rad));
- }
-}
-
-/*
-void PreMultiply_Alphas () //Ha ha, this isn't the kind of premultiplcation you're thinking of.
-{
- for (int y=0;y<64;y++)
- for (int x=0;x<64;x++)
- alphamultiply [y*64+x] = y*x;
-}
-*/
-
-int GetModifiedBackgroundImage() {
- return bgimgspr;
-}
-
-unsigned short root(unsigned short x) {
- unsigned short a, b;
- b = x;
- a = x = 0x3f;
- x = b / x;
- a = x = (x + a) >> 1;
- x = b / x;
- a = x = (x + a) >> 1;
- x = b / x;
- x = (x + a) >> 1;
- return (x);
-}
-
-
-float Hill(float x) {
- const float a0 = 1.0f;
- const float a2 = 2.0f / PI - 12.0f / (pisquared);
- const float a3 = 16.0f / (picubed) - 4.0f / (pisquared);
- const float xx = x * x;
- const float xxx = xx * x;
-
- return a0 + a2 * xx + a3 * xxx;
-}
-
-float FastSin(float x) {
- // wrap x within [0, TWO_PI)
- const float a = x * twopi_inv;
- x -= static_cast<int>(a) * twopi;
- if (x < 0.0f)
- x += twopi;
-
- // 4 pieces of hills
- if (x < halfpi)
- return Hill(halfpi - x);
- else if (x < PI)
- return Hill(x - halfpi);
- else if (x < 3.0f * halfpi)
- return -Hill(3.0f * halfpi - x);
- else
- return -Hill(x - 3.0f * halfpi);
-}
-
-float FastCos(float x) {
- return FastSin(x + halfpi);
-}
-
-FLOAT_RETURN_TYPE AGSFastSin(SCRIPT_FLOAT(x)) {
- INIT_SCRIPT_FLOAT(x);
- x = FastSin(x);
- RETURN_FLOAT(x);
-}
-
-FLOAT_RETURN_TYPE AGSFastCos(SCRIPT_FLOAT(x)) {
- INIT_SCRIPT_FLOAT(x);
- x = FastSin(x + halfpi);
- RETURN_FLOAT(x);
-}
-
-
-void DrawLens(int ox, int oy) {
- int32 sh, sw = 0;
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- BITMAP *virtsc = engine->GetVirtualScreen();
- if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen.");
- BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8);
- unsigned char **vScreen = engine->GetRawBitmapSurface(virtsc);
- unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite);
- int radius = LensOption.lenswidth >> 1;
- for (int y = 0; y < LensOption.lenswidth; y++) {
- int ypos = y * LensOption.lenswidth;
- for (int x = 0; x < LensOption.lenswidth; x++) {
- int lenspos = ypos + x;
- int coffx = lens[lenspos].xoffset;
- int coffy = lens[lenspos].yoffset;
- if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) {
- lensarray[y][x] = vScreen[oy + coffy][ox + coffx];
- //vScreen[oy+coffy][ox+coffx] = ABS(coffy);
- }
- }
- }
- /*
- for (int y=0;y<LensOption.lenswidth;y++)
- {
- int ypos = y*LensOption.lenswidth;
- for (int x=0;x<LensOption.lenswidth;x++)
- {
- if (oy+y > 0 && oy+y < sh && ox+x > 0 && ox+x < sw)
- {
- vScreen[oy+y][ox+x] = lensarray[y][x];
- }
- }
- }
- */
- int radsq = radius * radius;
- for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
- int cysq = cy * cy;
- for (int cx = -radius; cx <= radius; cx++) {
- int cxsq = cx * cx;
- int dx = cx + ox;
- int dy = cy + oy;
- if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) {
- //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong");
- vScreen[dy][dx] = lensarray[cy + radius][cx + radius];
- }
- }
- }
-
- engine->ReleaseBitmapSurface(lenswrite);
- engine->ReleaseBitmapSurface(virtsc);
- engine->FreeBitmap(lenswrite);
-}
-
-void SetLensPos(int x, int y) {
- LensOption.x = x;
- LensOption.y = y;
-}
-
-int GetLensX() {
- return LensOption.x;
-}
-
-int GetLensY() {
- return LensOption.y;
-}
-
-void SetLensDrawn(int toggle) {
- if (toggle > 0) LensOption.draw = 1;
- else LensOption.draw = 0;
-}
-
-int GetLensDrawn() {
- return LensOption.draw;
-}
-
-void SetLensOffsetClamp(int clamp) {
- if (clamp < 0) LensOption.clampoffset = LensOption.lenswidth;
- else LensOption.clampoffset = clamp;
-}
-
-int GetLensOffsetClamp() {
- return LensOption.clampoffset;
-}
-
-int GetLensLevel() {
- return LensOption.level;
-}
-
-void SetLensLevel(int level) {
- if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
- else LensOption.level = level;
-}
-
-void LensInitialize(int width, int zoom, int lensx, int lensy, int level, int clamp = -1) {
- int32 sw, sh, radius;
- if (width < 1) engine->AbortGame("Invalid lens dimension!");
- radius = width >> 1;
- lens = new LensDistort [width * width]();
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- int radsq = radius * radius;
- int zoomsq = zoom * zoom;
- for (int y = 0; y < radius; y++) {
- int ysq = y * y;
- for (int x = 0; x < radius; x++) {
- int lx, ly;
- int xsq = x * x;
- if ((xsq + ysq) < (radsq)) {
- float shift = zoom / sqrt((float)(zoomsq - (xsq + ysq - radsq)));
- lx = (int)(x * shift - x);
- ly = (int)(y * shift - y);
- } else {
- lx = 0;
- ly = 0;
- }
- lens[(radius - y)*width + (radius - x)].xoffset = lx;
- lens[(radius - y)*width + (radius - x)].yoffset = ly;
- lens[(radius + y)*width + (radius + x)].xoffset = -lx;
- lens[(radius + y)*width + (radius + x)].yoffset = -ly;
- lens[(radius + y)*width + (radius - x)].xoffset = lx;
- lens[(radius + y)*width + (radius - x)].yoffset = -ly;
- lens[(radius - y)*width + (radius + x)].xoffset = -lx;
- lens[(radius - y)*width + (radius + x)].yoffset = ly;
- }
- }
- LensOption.lenswidth = width;
- LensOption.lenszoom = zoom;
- if (clamp < 0) LensOption.clampoffset = width;
- else LensOption.clampoffset = clamp;
- LensOption.x = lensx;
- LensOption.y = lensy;
- if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
- else LensOption.level = level;
-}
-
-void ResetRemapping() {
- for (int j = 0; j < 256; ++j) {
- cycle_remap [j] = j;
- }
-}
-
-#define MAX_PLASMA_COMPLEXITY 4
-int plasmatype[MAX_PLASMA_COMPLEXITY];
-int plasmadata [MAX_PLASMA_COMPLEXITY];
-int plasmadata2 [MAX_PLASMA_COMPLEXITY];
-int plasmadata3 [MAX_PLASMA_COMPLEXITY];
-int plasmaroottype;
-
-
-void SetPlasmaRootType(int real) {
- if (real) plasmaroottype = 1;
- else plasmaroottype = 0;
-}
-
-int GetPlasmaRootType() {
- return plasmaroottype;
-}
-
-void SetPlasmaType(int component, int type, int data, int data2, int data3) {
- if (component >= MAX_PLASMA_COMPLEXITY) engine->AbortGame("Plasma too complex!");
- else {
- plasmatype [component] = type;
- plasmadata [component] = data;
- plasmadata2[component] = data2;
- plasmadata3[component] = data3;
- }
-
- //0 = None.
- //1 = Horizontal Bars (data=width)
- //2 = Vertical Bars (data=width)
- //3 = Circle (data=x,data2=y,data3=width)
- //4 = Diagonal Bars (data=width)
-}
-
-void ResetPlasmaSettings() {
- int i = 0;
- while (i < MAX_PLASMA_COMPLEXITY) {
- plasmatype [i] = 0;
- plasmadata [i] = 0;
- plasmadata2[i] = 0;
- plasmadata3[i] = 0;
- i++;
- }
-}
-
-void DrawPlasma(int slot, int palstart, int palend) {
- BITMAP *plasmaspr = engine->GetSpriteGraphic(slot);
- if (!plasmaspr) engine->AbortGame("Plasma: Not a sprite I can load.");
- int32 w, h, basecol, range = 0;
- if (palend > palstart) {
- range = palend - palstart;
- basecol = palstart;
- } else {
- range = palstart - palend;
- basecol = palend;
- }
- engine->GetBitmapDimensions(plasmaspr, &w, &h, nullptr);
- unsigned char **plasmarray = engine->GetRawBitmapSurface(plasmaspr);
- double frange = range / 2.0;
- int complex = 0;
- int color = 0;
- int i = 0;
- while (i < MAX_PLASMA_COMPLEXITY) {
- if (plasmatype[i] > 0) complex++;
- i++;
- }
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- color = 0;
- for (int p = 0; p < MAX_PLASMA_COMPLEXITY; p++) {
- if (plasmatype[p] == 1) { //1 = Horizontal Bars (data=width)
- color += int(frange + (frange * FastSin(y / (float)plasmadata[p])));
- } else if (plasmatype[p] == 2) { //2 = Vertical Bars (data=width)
- color += int(frange + (frange * FastSin(x / (float)plasmadata[p])));
- } else if (plasmatype[p] == 3) { //3 = Circle (data=x,data2=y,data3=width)
- int cx, cy = 0;
- cx = plasmadata [p];
- cy = plasmadata2 [p];
- if (plasmaroottype == 1) color += int(frange + (frange * FastSin(q3sqrt((float)((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
- else color += int(frange + (frange * FastSin(root(((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
- } else if (plasmatype[p] == 4) { //4 = Diagonal Bars (data=width)
- color += int(frange + (frange * FastSin((x + y) / (float)plasmadata[p])));
- }
- }
- if (color > 0 && complex > 0) color = color / complex;
- plasmarray[y][x] = static_cast<unsigned char>(basecol + color);
- }
- }
- engine->ReleaseBitmapSurface(plasmaspr);
- engine->NotifySpriteUpdated(slot);
-}
-
-void DoFire(int spriteId, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) {
- BITMAP *firespr = engine->GetSpriteGraphic(masksprite);
- BITMAP *firecolorspr = engine->GetSpriteGraphic(spriteId);
- BITMAP *seedspr;
- int32 w, h = 0;
- int range, basecol, dir = 0;
- if (palend > palstart) {
- range = palend - palstart;
- basecol = palstart;
- dir = 1;
- } else {
- range = palstart - palend;
- basecol = palend;
- dir = -1;
- }
- int divider = 256 / range;
- engine->GetBitmapDimensions(firespr, &w, &h, nullptr);
- unsigned char **fire = engine->GetRawBitmapSurface(firespr);
- unsigned char **color = engine->GetRawBitmapSurface(firecolorspr);
- int sparky = 0;
- //srand(time(NULL));
- for (int y = 0; y < h - 1; y++) {
- if ((int)::AGS::g_vm->getRandomNumber(9) > 7 - windspeed) { //Wind right
- for (int x = w - 1; x > 1; x--) {
- fire[y][x] = fire[y][x - 1];
- }
- } else if ((int)::AGS::g_vm->getRandomNumber(9) > 7 + windspeed) { // wind left
- for (int x = 0; x < w - 1; x++) {
- fire[y][x] = fire[y][x + 1];
- }
- }
- }
- for (int x = 0; x < w; x++) {
- sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
- if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
- ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
- fire[h - sparky][x] = 255;
- sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
- if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
- ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
- fire[h - sparky][x] = 0;
- }
- if (seed == 0) {
- for (int x = 0; x < w; x++)
- fire[h - 1][x] = 255;
- for (int x = 0; x < w; x++)
- fire[h - 2][x] = ::AGS::g_vm->getRandomNumber(255);
- } else if (seed > 0) {
- seedspr = engine->GetSpriteGraphic(seed);
- BITMAP *virtsc = engine->GetVirtualScreen();
- engine->SetVirtualScreen(firespr);
- engine->BlitBitmap(0, 0, seedspr, 1);
- engine->SetVirtualScreen(virtsc);
- engine->ReleaseBitmapSurface(virtsc);
- engine->ReleaseBitmapSurface(seedspr);
- engine->NotifySpriteUpdated(spriteId);
- engine->NotifySpriteUpdated(masksprite);
- }
-
- for (int y = 0; y < h - 1; y++) {
- for (int x = 0; x < w; x++) {
- fire[y][x] =
- ((fire[(y + 1) % h][(x - 1 + w) % w]
- + fire[(y + 1) % h][(x) % w]
- + fire[(y + 1) % h][(x + 1) % w]
- + fire[(y + 2) % h][(x) % w])
- * 100) / (400 + (100 - strength));
- if (fire[y][x] < cutoff) fire[y][x] = 0;
- //if (fire[y][x] ==255) color [y][x] = palend;
- else color [y][x] = static_cast<unsigned char>(basecol + (fire[y][x] / divider) * dir);
- }
- }
- engine->ReleaseBitmapSurface(firespr);
- engine->ReleaseBitmapSurface(firecolorspr);
- engine->NotifySpriteUpdated(spriteId);
- engine->NotifySpriteUpdated(masksprite);
-}
-
-/*
-unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha)
-{
- //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette ();
- int i=0;
- int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
- int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
- int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
- //unsigned char ralpha = alpha>>2;
- //unsigned char invralpha = 64-ralpha;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //int out_r = alphamultiply[(palette[fg].r>>1)][ralpha] + alphamultiply[(palette[bg].r>>1)][(invralpha)];
- //int out_g = alphamultiply[(palette[fg].g)][ralpha] + alphamultiply[(palette[bg].g)][(invralpha)];
- //int out_b = alphamultiply[(palette[fg].b>>1)][ralpha] + alphamultiply[(palette[bg].b>>1)][(invralpha)];
- out_r = (out_r + 1 + (out_r >> 8)) >> 8;
- out_g = (out_g + 1 + (out_g >> 8)) >> 8;
- out_b = (out_b + 1 + (out_b >> 8)) >> 8;
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-
-unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha)
-{
- //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette ();
- int i=0;
- int add_r,add_b,add_g = 0;
- char ralpha = alpha>>2;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //add_r = (((palette[fg].r>>1) * (alpha))>>8);
- //add_b = (((palette[fg].b>>1) * (alpha))>>8);
- //add_g = (((palette[fg].g) * (alpha))>>8);
- add_r = ((alphamultiply[(palette[fg].r>>1)*64+ralpha])>>6);
- add_b = ((alphamultiply[(palette[fg].b>>1)*64+ralpha])>>6);
- add_g = ((alphamultiply[(palette[fg].g )*64+ralpha])>>6);
- int out_r = min(31,(palette[bg].r>>1) + add_r);
- int out_g = min(63, palette[bg].g + add_g);
- int out_b = min(31,(palette[bg].b>>1) + add_b);
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-*/
-unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b) {
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- int i = ((r << 11) | (g << 5) | b);
- unsigned char (*clutp) = clut;
- unsigned char result = *(clutp + i);
- result = cycle_remap [result]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
-}
-
-void CycleRemap(int start, int end) {
- if (end > start) {
- // Rotate left
- int wraparound = cycle_remap [start];
- for (; start < end; ++start) {
- cycle_remap [start] = cycle_remap [start + 1];
- }
- cycle_remap [end] = wraparound;
- } else if (end < start) {
- // Rotate right
- int wraparound = cycle_remap [start];
- for (; start > end; --start) {
- cycle_remap [start] = cycle_remap [start - 1];
- }
- cycle_remap [end] = wraparound;
-
- }
-}
-
-unsigned char GetRemappedSlot(unsigned char slot) {
- return cycle_remap [slot];
-}
-
-int LoadCLUT(int slot) {
- if (engine->GetSpriteWidth(slot) != 256 || engine->GetSpriteHeight(slot) != 256) return 1;
- BITMAP *clutimage = engine->GetSpriteGraphic(slot);
- unsigned char **clutarray = engine->GetRawBitmapSurface(clutimage);
- for (int y = 0; y < 256; y++) {
- for (int x = 0; x < 256; x++) {
- clut[y * 256 + x] = clutarray[y][x];
- }
- }
- clutslot = slot;
- engine->ReleaseBitmapSurface(clutimage);
- return 0;
-}
-
-void SetReflections(int toggle) {
- drawreflections = toggle;
-}
-
-int IsReflectionsOn() {
- return drawreflections;
-}
-
-int GetLuminosityFromPalette(int slot) {
- AGSColor *pal = engine->GetPalette();
- int lum = (pal[slot].r +
- pal[slot].r +
- pal[slot].r +
- pal[slot].g +
- pal[slot].g +
- pal[slot].g +
- pal[slot].g +
- pal[slot].b) >> 3;
- return lum;
-}
-
-
-
-void SetStarsOriginPoint(int x, int y) {
- Starfield.originx = x;
- Starfield.originy = y;
-}
-void InitializeStars(int slot, int maxstars) {
- int32 sw, sh = 0;
- BITMAP *canvas = engine->GetSpriteGraphic(slot);
- engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
- Starfield.maxstars = maxstars;
- Starfield.overscan = 20;
- stars = new starstype [Starfield.maxstars];
- for (int i = 0; i < Starfield.maxstars; i++) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh;
- stars[i].z = (float)(MAX_DEPTH);
- stars[i].color = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 240);
- stars[i].sprite = 0;
- stars[i].maxrad = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 5);
- }
-}
-
-void IterateStars(int slot) {
- long sw, sh = 0;
- sw = engine->GetSpriteWidth(slot);
- sh = engine->GetSpriteHeight(slot);
- for (int i = 0; i < Starfield.maxstars; i++) {
- stars[i].z -= Starfield.speed;
- //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
- float k = Starfield.depthmultiplier / stars[i].z;
- int px = static_cast<int>(stars[i].x * k + Starfield.originx);
- int py = static_cast<int>(stars[i].y * k + Starfield.originy);
- if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
- stars[i].z = (float)MAX_DEPTH;
- //stars[i].color = (rand () %240);
- }
- }
-}
-int GetStarfieldOverscan() {
- return Starfield.overscan;
-}
-void SetStarfieldOverscan(int overscan) {
- Starfield.overscan = overscan;
-}
-
-int GetStarfieldOriginX() {
- return Starfield.originx;
-}
-
-int GetStarfieldOriginY() {
- return Starfield.originy;
-}
-
-void SetStarfieldDepthMultiplier(int multi) {
- Starfield.depthmultiplier = multi;
-}
-
-int GetStarfieldDepthMultiplier() {
- return Starfield.depthmultiplier;
-}
-
-int GetStarfieldMaxStars() {
- return Starfield.maxstars;
-}
-
-void SetStarSpriteScaleBoost(int star, int boost) {
- stars[star].scaleboost = boost;
-}
-
-int GetStarSpriteScaleBoost(int star) {
- return stars[star].scaleboost;
-}
-
-void SetStarMaxRadius(int star, int radius) {
- stars[star].maxrad = radius;
-}
-
-int GetStarMaxRadius(int star) {
- return stars[star].maxrad;
-}
-
-void RotateStar(int star, int angle, int px, int py) {
- float rsin = rot_sine_LUT[angle];
- float rcos = rot_cos_LUT[angle];
- float fPx = (float)px;
- float fPy = (float)py;
- float x1 = 0, y1 = 0, xRot = 0, yRot = 0;
- int i = star;
- x1 = stars[i].x;
- y1 = stars[i].y;
- xRot = fPx + rcos * (x1 - fPx) - rsin * (y1 - fPy);
- yRot = fPy + rsin * (x1 - fPx) + rcos * (y1 - fPy);
- stars[i].x = xRot;
- stars[i].y = yRot;
- i++;
-}
-
-FLOAT_RETURN_TYPE GetStarX(int i) {
- float starx = (float)stars[i].x;
- RETURN_FLOAT(starx);
-}
-
-FLOAT_RETURN_TYPE GetStarY(int i) {
- float stary = (float)stars[i].y;
- RETURN_FLOAT(stary);
-}
-
-FLOAT_RETURN_TYPE GetStarZ(int i) {
- float starz = (float)stars[i].z;
- RETURN_FLOAT(starz);
-}
-
-void SetStarPosition(int star, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), SCRIPT_FLOAT(z)) {
- INIT_SCRIPT_FLOAT(x);
- INIT_SCRIPT_FLOAT(y);
- INIT_SCRIPT_FLOAT(z);
- stars[star].x = x;
- stars[star].y = y;
- stars[star].z = z;
-}
-
-void SetStarColor(int star, unsigned char color) {
- stars[star].color = color;
-}
-
-unsigned char GetStarColor(int star) {
- return stars[star].color;
-}
-
-void SetStarSprite(int star, int slot) {
- stars[star].sprite = slot;
-}
-
-int GetStarSprite(int star) {
- return stars[star].sprite;
-}
-
-void SetStarSpriteRange(int start, int end, int slot) {
- int sfix = start;
- int efix = end;
- if (start > Starfield.maxstars) sfix = Starfield.maxstars - 1;
- if (end > Starfield.maxstars) efix = Starfield.maxstars;
- for (int i = sfix; i < efix; i++)
- stars[i].sprite = slot;
-}
-
-void DrawStars(int slot, int maskslot) {
- int32 sw, sh = 0;
- BITMAP *canvas = engine->GetSpriteGraphic(slot);
- if (!canvas) engine->AbortGame("DrawStars: Can't load sprite slot.");
- BITMAP *maskcanvas = engine->GetSpriteGraphic(maskslot);
- if (!maskcanvas) engine->AbortGame("DrawStars: Can't load mask slot.");
- engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
- unsigned char **screenarray = engine->GetRawBitmapSurface(canvas);
- unsigned char **maskarray = engine->GetRawBitmapSurface(maskcanvas);
- for (int i = 0; i < Starfield.maxstars; i++) {
- //stars[i].z-= 0.5;
- //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
- float k = (float)Starfield.depthmultiplier / stars[i].z;
- int px = static_cast<int>(stars[i].x * k + Starfield.originx);
- int py = static_cast<int>(stars[i].y * k + Starfield.originy);
- if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
- stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
- if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
- stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
- if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
- stars[i].z = (float)MAX_DEPTH;
- //stars[i].color = (rand () %240);
- } else if (stars[i].z > 0) {
- int ivalue = (63 - (int)stars[i].z);
- if (ivalue > 63) ivalue = 63;
- else if (ivalue < 0) ivalue = 0;
- unsigned char value = (unsigned char)(ivalue);
- unsigned char maskcolor = value << 2;
- if (stars[i].sprite > 0) {
- BITMAP *origspr = engine->GetSpriteGraphic(stars[i].sprite);
- int scale = (ivalue + 1) * 100 >> 6;
- //int scale = 50;
- if (scale < 1) scale = 1;
- /*
- if (scale != 100)
- {
- unsigned char** orig = engine->GetRawBitmapSurface (origspr);
- int32 h1,h2,w1,w2=0;
- double fw2,fh2;
- engine->GetBitmapDimensions (origspr,&w1,&h1,NULL);
- fh2 = h1 * (scale / 100.0);
- fw2 = w1 * (scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- if (w2 < 1) w2 = 1;
- if (h2 < 1) h2 = 1;
- resizspr = engine->CreateBlankBitmap (w2,h2,8);
- unsigned char** resized = engine->GetRawBitmapSurface (resizspr);
- int x_ratio = (int)((w1<<16)/w2) +1;
- int y_ratio = (int)((h1<<16)/h2) +1;
- int x2, y2 ;
- for (int i=0;i<h2;i++)
- {
- for (int j=0;j<w2;j++)
- {
- x2 = ((j*x_ratio)>>16) ;
- y2 = ((i*y_ratio)>>16) ;
- resized [i][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface (resizspr);
- }
- //resizspr = origspr;
- int32 w,h=0;
- engine->GetBitmapDimensions (resizspr,&w,&h,NULL);
- unsigned char **imagemap = engine->GetRawBitmapSurface (resizspr);
- int ox = px - (w>>1);
- int oy = py - (h>>1);
- for (int dy=0;dy<h;dy++)
- {
- for (int dx=0;dx<w;dx++)
- {
- int ex = ox+dx;
- int ey = oy+dy;
- if (ex < sw && ex >= 0 && ey < sh && ey >= 0)
- {
- if (maskcolor > maskarray [ey][ex] && imagemap[dy][dx] > 0)
- {
- maskarray [ey][ex] = maskcolor;
- screenarray [ey][ex] = imagemap[dy][dx];
- }
- }
- }
- }
- */
-
- unsigned char **orig = engine->GetRawBitmapSurface(origspr);
- int32 h1, h2, w1, w2 = 0;
- double fw2, fh2;
- engine->GetBitmapDimensions(origspr, &w1, &h1, nullptr);
- fh2 = h1 * (scale / 100.0);
- fw2 = w1 * (scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- if (w2 < 1) w2 = 1;
- if (h2 < 1) h2 = 1;
- int x_ratio = (int)((w1 << 16) / w2) + 1;
- int y_ratio = (int)((h1 << 16) / h2) + 1;
- int x2, y2 ;
- int ox = px - (w2 >> 1);
- int oy = py - (h2 >> 1);
- for (int ii = 0; ii < h2; ii++) {
- int temprzy = ii * y_ratio;
- int ey = oy + ii;
- for (int j = 0; j < w2; j++) {
- x2 = ((j * x_ratio) >> 16);
- y2 = ((temprzy) >> 16);
- int ex = ox + j;
- if (ex < sw && ex >= 0 && ey < sh && ey >= 0) {
- if (maskcolor > maskarray [ey][ex] && orig[y2][x2] > 0) {
- maskarray [ey][ex] = maskcolor;
- screenarray [ey][ex] = orig[y2][x2];
- }
- }
- //resized [ii][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface(origspr);
- } else if (stars[i].sprite == 0) {
- if (stars[i].maxrad == 1) {
- if (px < sw && px >= 0 && py < sh && py >= 0) {
- if (maskcolor > maskarray[py][px]) {
- maskarray[py][px] = maskcolor;
- screenarray[py][px] = stars[i].color;
- }
- }
- } else {
- int scale = ((((int)stars[i].z) * 100) / 63);
- if (scale < 1) scale = 1;
- int radius = (stars[i].maxrad * (100 - scale) / 100);
- int radsq = radius * radius;
- //unsigned char color = GetColor565 (value>>1,value,value>>1);
- unsigned char color = stars[i].color;
- for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
- int cysq = cy * cy;
- for (int cx = -radius; cx <= radius; cx++) {
- int cxsq = cx * cx;
- int dx = cx + px;
- int dy = cy + py;
- if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) {
- if (maskcolor > maskarray [dy][dx]) {
- maskarray [dy][dx] = maskcolor;
- screenarray [dy][dx] = color;
- }
- }
- }
- }
- /*
- for(int cy=-radius; cy<=radius; cy++) //Draw a circle around the point, for the color.
- {
- int cysq = cy*cy;
- for(int cx=-radius; cx<=radius; cx++)
- {
- int cxsq = cx*cx;
- int dx = cx+px;
- int dy = cy+py;
- if((cxsq+cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0)
- {
- if (maskarray [dy][dx] == maskcolor)screenarray [dy][dx] = color;
- }
- }
- }
- */
- }
- }
- }
- }
- engine->ReleaseBitmapSurface(canvas);
- engine->ReleaseBitmapSurface(maskcanvas);
- engine->NotifySpriteUpdated(slot);
- engine->NotifySpriteUpdated(maskslot);
-}
-
-
-int CreateTranslucentOverlay(int id, int spriteId, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) {
- BITMAP *testspr = engine->GetSpriteGraphic(spriteId);
- if (testspr) overlay[id].sprite = spriteId;
- else engine->AbortGame("CreateTranslucentOverlay: Invalid spriteId.");
- engine->ReleaseBitmapSurface(testspr);
- overlay[id].level = MAX(0, MIN(level, 4));
- overlay[id].trans = MAX(0, MIN(alpha, 255));
- overlay[id].spritemask = mask;
- overlay[id].x = ox;
- overlay[id].y = oy;
- overlay[id].enabled = true;
- overlay[id].blendtype = blendmode;
- return 0;
-}
-
-int DeleteTranslucentOverlay(int id) {
- overlay[id].enabled = false;
- overlay[id].sprite = 0;
- overlay[id].x = 0;
- overlay[id].y = 0;
- overlay[id].level = 0;
- overlay[id].trans = 0;
- return 0;
-}
-
-int MoveTranslucentOverlay(int id, int ox, int oy) {
- overlay[id].x = ox;
- overlay[id].y = oy;
- return 0;
-}
-
-int GetTranslucentOverlayX(int id) {
- return overlay[id].x;
-}
-
-int GetTranslucentOverlayY(int id) {
- return overlay[id].y;
-}
-
-int GetTranslucentOverlaySprite(int id) {
- return overlay[id].sprite;
-}
-
-int GetTranslucentOverlayLevel(int id) {
- return overlay[id].level;
-}
-
-int GetTranslucentOverlayEnabled(int id) {
- return overlay[id].enabled;
-}
-
-int GetTranslucentOverlayAlpha(int id) {
- return overlay[id].trans;
-}
-
-int SetTranslucentOverlayAlpha(int id, int alpha) {
- if (alpha >= 0 && alpha < 256)
- overlay[id].trans = alpha;
- else
- engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected.");
- return 0;
-}
-
-int SetTranslucentOverlayEnabled(int id, int toggle) {
- if (toggle > 0)
- overlay[id].enabled = true;
- else
- overlay[id].enabled = false;
- return 0;
-}
-
-void SetCharacterReflected(int id, int refl) {
- if (refl > 0) Reflection.Characters[id].reflect = 1;
- else Reflection.Characters[id].reflect = 0;
-}
-
-void SetObjectReflected(int id, int refl) {
- if (refl > 0)
- Reflection.Objects[id].reflect = 1;
- else
- Reflection.Objects[id].reflect = 0;
-}
-
-int GetCharacterReflected(int id) {
- return Reflection.Characters[id].reflect;
-}
-
-int GetObjectReflected(int id) {
- return Reflection.Objects[id].reflect;
-}
-
-void ReplaceCharacterReflectionView(int id, int view) {
- Reflection.Characters[id].replaceview = view - 1;
-}
-
-void SetObjectReflectionIgnoreScaling(int id, int wb) {
- if (wb) Reflection.Objects[id].ignorescaling = 1;
- else Reflection.Objects[id].ignorescaling = 0;
-}
-
-int DrawReflections(int id, int charobj = 0) {
- int32 screenw, screenh;
- int32 bgw, bgh;
- engine->GetScreenDimensions(&screenw, &screenh, nullptr);
- BITMAP *bgmask = engine->GetBackgroundScene(1);
- if (bgmask == nullptr) return 1;
- //BITMAP *virtsc = engine->GetVirtualScreen();
- BITMAP *walkbehind = engine->GetRoomMask(MASK_WALKBEHIND);
- //if (!virtsc) engine->AbortGame ("Can't load virtual screen.");
- if (!walkbehind) engine->AbortGame("DrawRelfections: Can't load Walkbehind into memory.");
- engine->GetBitmapDimensions(walkbehind, &bgw, &bgh, nullptr);
- if (!bgmask) engine->AbortGame("DrawReflections: Can't load reflection mask.");
- //unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc);
- unsigned char **wbarray = engine->GetRawBitmapSurface(walkbehind);
- unsigned char **maskarray = engine->GetRawBitmapSurface(bgmask);
- //Initialize stuff
- BITMAP *charsprite = nullptr;
- BITMAP *charsprite2 = nullptr;
- AGSCharacter *currchar = nullptr;
- AGSObject *currobj;
- int cox = 0, coy = 0, coz = 0;
- int scale = 0;
- //Get character, and their sprite.
- if (charobj == 0) {
- currchar = engine->GetCharacter(id);
- /*int view = 0;
- if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1;
- else view = Reflection.Characters[id].replaceview;
- */
- AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame);
- charsprite = engine->GetSpriteGraphic(vf->pic);
- long scaling = currchar->flags & CHF_NOSCALING;
- if (!scaling)scale = engine->GetAreaScaling(currchar->x, currchar->y);
- else scale = 100;
- cox = currchar->x;
- coy = currchar->y;
- coz = currchar->z;
- } else if (charobj == 1) {
- currobj = engine->GetObject(id);
-
- charsprite = engine->GetSpriteGraphic(currobj->num);
- if (Reflection.Objects[id].ignorescaling) scale = 100;
- else scale = engine->GetAreaScaling(currobj->x, currobj->y);
- cox = currobj->x;
- if (currobj->baseline < 0) coy = currobj->y;
- else coy = currobj->baseline;
- coz = 0;
- }
- bool scaled = false;
- int32 w, h;
- engine->GetBitmapDimensions(charsprite, &w, &h, nullptr);
- if (scale != 100) {
- unsigned char **orig = engine->GetRawBitmapSurface(charsprite);
- int h1, h2, w1, w2;
- double fw2, fh2;
- h1 = h;
- w1 = w;
- fh2 = h1 * ((double)scale / 100.0);
- fw2 = w1 * ((double)scale / 100.0);
- h2 = static_cast<int>(fh2);
- w2 = static_cast<int>(fw2);
- charsprite2 = engine->CreateBlankBitmap(w2, h2, 8);
- unsigned char **resized = engine->GetRawBitmapSurface(charsprite2);
- int x_ratio = (int)((w1 << 16) / w2) + 1;
- int y_ratio = (int)((h1 << 16) / h2) + 1;
- int x2, y2 ;
- for (int i = 0; i < h2; i++) {
- for (int j = 0; j < w2; j++) {
- x2 = ((j * x_ratio) >> 16) ;
- y2 = ((i * y_ratio) >> 16) ;
- resized [i][j] = orig [y2][x2];
- }
- }
- engine->ReleaseBitmapSurface(charsprite2);
- scaled = true;
- w = w2;
- h = h2;
- } else {
- charsprite2 = charsprite;
- }
- int transamount = 0;
- unsigned char **spritearray = engine->GetRawBitmapSurface(charsprite2);
- unsigned char **charbuffer = engine->GetRawBitmapSurface(rcolormap);
- unsigned char **alphaarray = engine->GetRawBitmapSurface(ralphamap);
- int i = h - 1, j = 0;
- int32 ox = cox;
- if (charobj == 0) ox = ox - (w / 2);
- int32 oy = coy + coz - 1;
- engine->RoomToViewport(&ox, &oy);
- int yoffset = 0;
- int translevel = 7;
- //bool dither = false;
- //bool dodither = false;
- int counter = 0;
- int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0));
- int delay = screenh / rowcount;
- int *obst;
- int flipped = 0;
- if (charobj == 0) {
- int (*sfGetGameParameter)(int, int, int, int);
- sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
- flipped = sfGetGameParameter(13, currchar->view + 1, currchar->loop, currchar->frame);
- } else flipped = 0;
- obst = new int [w];
- for (int k = 0; k < w; k++) {
- obst[k] = 0;
- }
- while (i > 0) {
- //if ((counter == delay/2-1 || counter == delay-1) && yoffset < 36) dodither = (!dodither);
- if (counter == delay) {
- counter = 0;
- if (translevel > 0) translevel--;
- } else counter++;
- yoffset++;
- while (j < w) {
- int xoffset;
- if (flipped == 1) xoffset = w - j - 1;
- else xoffset = j;
- int32 rx = ox + xoffset, ry = oy + yoffset;
- int wbb = 0;
- engine->ViewportToRoom(&rx, &ry);
- if (ry > 0 && ry < bgh && rx > 0 && rx < bgw) {
- if (wbarray [ry][rx] > 0) {
- wbb = engine->GetWalkbehindBaseline(wbarray[ry][rx]);
- }
- if (maskarray[ry][rx] == 21) obst[j] = 1;
- }
-
- //dither = (!dither);
- transamount = 32 * translevel;
- if (spritearray [i][j] != 0 && oy + yoffset < screenh && ox + xoffset < screenw && oy + yoffset >= 0 && ox + xoffset >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg.
- if (wbb < ry && obst[j] == 0 && (oy > reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))])) {
- //charbuffer[oy+yoffset][ox+xoffset] = MixColorAlpha (spritearray [i][j],charbuffer[oy+yoffset][ox+xoffset],transamount);
- charbuffer [oy + yoffset][ox + xoffset] = spritearray [i][j];
- alphaarray [oy + yoffset][ox + xoffset] = transamount;
- reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))] = oy;
- }
- }
- j++;
- }
- //if (w % 2 == 0) dither = (!dither);
- i--;
- j = 0;
- }
-
- delete [] obst;
- if (scaled == true)engine->FreeBitmap(charsprite2);
- engine->ReleaseBitmapSurface(charsprite);
- //engine->ReleaseBitmapSurface (virtsc);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(bgmask);
- engine->ReleaseBitmapSurface(walkbehind);
- engine->ReleaseBitmapSurface(rcolormap);
- engine->ReleaseBitmapSurface(ralphamap);
- engine->MarkRegionDirty(ox, oy, ox + w, oy + h);
- return 0;
-}
-
-
-int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) {
- BITMAP *maskspr = nullptr;
- unsigned char **maskarray = nullptr;
- if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
- if (!maskspr && mask > 0) {
- char maskerr [100];
- snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
- engine->AbortGame(maskerr);
- }
- // Get a reference to the screen we'll draw onto
- BITMAP *bgspr = engine->GetSpriteGraphic(bg);
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
- if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background");
- //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
- if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay spriteId into memory.");
- // Get its surface
- int32 sprw, sprh, coldepth;
- int32 bgw, bgh;
- engine->GetBitmapDimensions(bgspr, &bgw, &bgh, &coldepth);
- engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
-
- unsigned char **bgarray = engine->GetRawBitmapSurface(bgspr);
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
- if (mask > 0) maskarray = engine->GetRawBitmapSurface(maskspr);
- int tloffset = 255 - translevel;
- int x = 0;
- int y = 0;
- //int transamount = 256 * translevel; //old
- while (y < sprh) {
- while (x < sprw) {
- if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the bg.
- if (mask > 0) {
- translevel = MAX(maskarray [y][x] - tloffset, 0);
- }
- //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
- if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
- else if (blendmode == 1) spritearray[y][x] = Mix::MixColorAdditive(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
- }
- x++;
- }
- x = 0;
- y++;
- }
-
- // Release the screen so that the engine can continue
- engine->ReleaseBitmapSurface(bgspr);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(spritespr);
- engine->NotifySpriteUpdated(spriteId);
- return 0;
-}
-
-int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) {
- if (translevel == 0) return 0;
- BITMAP *maskspr = nullptr;
- unsigned char **maskarray = nullptr;
- // Get a reference to the screen we'll draw onto
- BITMAP *virtsc = engine->GetVirtualScreen();
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
- if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
- if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen.");
- //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
- if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay spriteId into memory.");
- // Get its surface
- int32 sprw, sprh, coldepth;
- int32 screenw, screenh;
- engine->GetScreenDimensions(&screenw, &screenh, &coldepth);
- engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
- unsigned char **charbuffer = engine->GetRawBitmapSurface(virtsc);
- unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
- if (mask > 0) {
- if (!maskspr && mask > 0) {
- char maskerr [100];
- snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
- engine->AbortGame(maskerr);
- }
- maskarray = engine->GetRawBitmapSurface(maskspr);
- }
- int tloffset = 255 - translevel;
- int x = 0;
- int y = 0;
- //int transamount = 256 * translevel; //old
- while (y < sprh) {
- while (x < sprw) {
- if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the screen.
- //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
- if (mask > 0) {
- translevel = MAX(maskarray [y][x] - tloffset, 0);
- }
- if (blendmode == 0) {
- if (translevel == 255) {
- charbuffer[y + oy][x + ox] = spritearray [y][x];
- } else charbuffer[y + oy][x + ox] = Mix::MixColorAlpha(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
- } else if (blendmode == 1) charbuffer[y + oy][x + ox] = Mix::MixColorAdditive(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
- }
- x++;
- }
- x = 0;
- y++;
- }
-
- // Release the screen so that the engine can continue
- long dirtywidth = ox + sprw;
- if (dirtywidth > screenw) dirtywidth = screenw - 1;
- long dirtyheight = oy + sprh;
- if (dirtyheight > screenh) dirtywidth = screenh - 1;
- engine->ReleaseBitmapSurface(virtsc);
- //engine->ReleaseBitmapSurface (clutspr);
- engine->ReleaseBitmapSurface(spritespr);
- if (mask > 0) engine->ReleaseBitmapSurface(maskspr);
- engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight);
-
- return 0;
-}
-
-/*------------------------------------------------------------------*/
-
-AGSPalRender::AGSPalRender() : DLL() {
- DLL_METHOD(AGS_GetPluginName);
- DLL_METHOD(AGS_EngineStartup);
- DLL_METHOD(AGS_EngineShutdown);
- DLL_METHOD(AGS_EngineOnEvent);
-}
-
-const char *AGSPalRender::AGS_GetPluginName() {
- return "PALgorithms Translucent Overlay Renderer";
-}
-
-void AGSPalRender::AGS_EngineStartup(IAGSEngine *lpEngine) {
- engine = lpEngine;
-
- // Make sure it's got the version with the features we need
- if (engine->version < 3) {
- engine->AbortGame("Engine interface is too old, need newer version of AGS.");
- }
- engine->RegisterScriptFunction("PALInternal::LoadCLUT^1", (void *)LoadCLUT);
- engine->RegisterScriptFunction("PALInternal::CycleRemap^2", (void *)CycleRemap);
- engine->RegisterScriptFunction("PALInternal::GetColor565^3", (void *)GetColor565);
- engine->RegisterScriptFunction("PALInternal::GetLuminosityFromPalette^1", (void *)GetLuminosityFromPalette);
- engine->RegisterScriptFunction("PALInternal::FastSin^1", (void *)AGSFastSin);
- engine->RegisterScriptFunction("PALInternal::FastCos^1", (void *)AGSFastCos);
- engine->RegisterScriptFunction("PALInternal::FastRoot^1", (void *)root);
- engine->RegisterScriptFunction("PALInternal::GetRemappedSlot^1", (void *)GetRemappedSlot);
- engine->RegisterScriptFunction("PALInternal::ResetRemapping^0", (void *)ResetRemapping);
- engine->RegisterScriptFunction("PALInternal::GetModifiedBackgroundImage", (void *)GetModifiedBackgroundImage);
- engine->RegisterScriptFunction("PALInternal::WriteObjectivePalette^4", (void *)WriteObjectivePalette);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteR^1", (void *)ReadObjectivePaletteR);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteB^1", (void *)ReadObjectivePaletteB);
- engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteG^1", (void *)ReadObjectivePaletteG);
-
- engine->RegisterScriptFunction("Raycast::Render^1", (void *)Raycast_Render);
- engine->RegisterScriptFunction("Raycast::LoadMap^4", (void *)LoadMap);
- engine->RegisterScriptFunction("Raycast::Initialize", (void *)Init_Raycaster);
- engine->RegisterScriptFunction("Raycast::MakeTextures^1", (void *)MakeTextures);
- engine->RegisterScriptFunction("Raycast::MoveForward^0", (void *)MoveForward);
- engine->RegisterScriptFunction("Raycast::MoveBackward^0", (void *)MoveBackward);
- engine->RegisterScriptFunction("Raycast::RotateLeft^0", (void *)RotateLeft);
- engine->RegisterScriptFunction("Raycast::RotateRight^0", (void *)RotateRight);
- engine->RegisterScriptFunction("Raycast::SetCameraPosition^2", (void *)Ray_SetPlayerPosition);
- engine->RegisterScriptFunction("Raycast::GetCameraX^0", (void *)Ray_GetPlayerX);
- engine->RegisterScriptFunction("Raycast::GetCameraY^0", (void *)Ray_GetPlayerY);
- engine->RegisterScriptFunction("Raycast::GetCameraAngle^0", (void *)Ray_GetPlayerAngle);
- engine->RegisterScriptFunction("Raycast::SetCameraAngle^1", (void *)Ray_SetPlayerAngle);
- engine->RegisterScriptFunction("Raycast::InitSprite^9", (void *)Ray_InitSprite);
- engine->RegisterScriptFunction("Raycast::UnloadEngine^0", (void *)QuitCleanup);
- engine->RegisterScriptFunction("Raycast::GetHotspotAtXY^2", (void *)Ray_GetHotspotAt);
- engine->RegisterScriptFunction("Raycast::GetObjectAtXY^2", (void *)Ray_GetObjectAt);
- engine->RegisterScriptFunction("Raycast::SetSpriteInteractObj^2", (void *)Ray_SetSpriteInteractObj);
- engine->RegisterScriptFunction("Raycast::GetSpriteInteractObj^1", (void *)Ray_GetSpriteInteractObj);
- engine->RegisterScriptFunction("Raycast::SetSpritePosition^3", (void *)Ray_SetSpritePosition);
- engine->RegisterScriptFunction("Raycast::SetSpriteVertOffset^2", (void *)Ray_SetSpriteVertOffset);
- engine->RegisterScriptFunction("Raycast::GetSpriteVertOffset^1", (void *)Ray_GetSpriteVertOffset);
- engine->RegisterScriptFunction("Raycast::GetSpriteX^1", (void *)Ray_GetSpriteX);
- engine->RegisterScriptFunction("Raycast::GetSpriteY^1", (void *)Ray_GetSpriteY);
- engine->RegisterScriptFunction("Raycast::SetWallHotspot^2", (void *)Ray_SetWallHotspot);
- engine->RegisterScriptFunction("Raycast::SetWallTextures^5", (void *)Ray_SetWallTextures);
- engine->RegisterScriptFunction("Raycast::SetWallSolid^5", (void *)Ray_SetWallSolid);
- engine->RegisterScriptFunction("Raycast::SetWallIgnoreLighting^5", (void *)Ray_SetWallIgnoreLighting);
- engine->RegisterScriptFunction("Raycast::SetWallAlpha^5", (void *)Ray_SetWallAlpha);
- engine->RegisterScriptFunction("Raycast::SetWallBlendType^5", (void *)Ray_SetWallBlendType);
- engine->RegisterScriptFunction("Raycast::GetMoveSpeed^0", (void *)Ray_GetMoveSpeed);
- engine->RegisterScriptFunction("Raycast::SetMoveSpeed^1", (void *)Ray_SetMoveSpeed);
- engine->RegisterScriptFunction("Raycast::GetRotSpeed^0", (void *)Ray_GetRotSpeed);
- engine->RegisterScriptFunction("Raycast::SetRotSpeed^1", (void *)Ray_SetRotSpeed);
- engine->RegisterScriptFunction("Raycast::GetWallAt^2", (void *)Ray_GetWallAt);
- engine->RegisterScriptFunction("Raycast::GetLightAt^2", (void *)Ray_GetLightAt);
- engine->RegisterScriptFunction("Raycast::SetLightAt^3", (void *)Ray_SetLightAt);
- engine->RegisterScriptFunction("Raycast::SetWallAt^3", (void *)Ray_SetWallAt);
- engine->RegisterScriptFunction("Raycast::SetPlaneY^1", (void *)Ray_SetPlaneY);
- engine->RegisterScriptFunction("Raycast::GetDistanceAt^2", (void *)Ray_GetDistanceAt);
- engine->RegisterScriptFunction("Raycast::GetSpriteAngle^1", (void *)Ray_GetSpriteAngle);
- engine->RegisterScriptFunction("Raycast::SetSpriteAngle^2", (void *)Ray_SetSpriteAngle);
- engine->RegisterScriptFunction("Raycast::SetSpriteView^2", (void *)Ray_SetSpriteView);
- engine->RegisterScriptFunction("Raycast::GetSpriteView^1", (void *)Ray_GetSpriteView);
- engine->RegisterScriptFunction("Raycast::SetSpriteFrame^2", (void *)Ray_SetSpriteFrame);
- engine->RegisterScriptFunction("Raycast::GetSpriteFrame^1", (void *)Ray_GetSpriteFrame);
- engine->RegisterScriptFunction("Raycast::SetSpritePic^2", (void *)Ray_SetSpritePic);
- engine->RegisterScriptFunction("Raycast::GetSpritePic^1", (void *)Ray_GetSpritePic);
- engine->RegisterScriptFunction("Raycast::SetSkyBox^1", (void *)Ray_SetSkyBox);
- engine->RegisterScriptFunction("Raycast::SetSpriteAlpha^2", (void *)Ray_SetSpriteAlpha);
- engine->RegisterScriptFunction("Raycast::GetSpriteAlpha^1", (void *)Ray_GetSpriteAlpha);
- engine->RegisterScriptFunction("Raycast::GetSkyBox^1", (void *)Ray_GetSkyBox);
- engine->RegisterScriptFunction("Raycast::SetAmbientLight^1", (void *)Ray_SetAmbientLight);
- engine->RegisterScriptFunction("Raycast::SetAmbientColor^2", (void *)Ray_SetAmbientColor);
- engine->RegisterScriptFunction("Raycast::GetAmbientLight^0", (void *)Ray_GetAmbientLight);
- engine->RegisterScriptFunction("Raycast::GetAmbientWeight^0", (void *)Ray_GetAmbientWeight);
- engine->RegisterScriptFunction("Raycast::GetTileX_At^2", (void *)Ray_GetTileX_At);
- engine->RegisterScriptFunction("Raycast::GetTileY_At^2", (void *)Ray_GetTileY_At);
- engine->RegisterScriptFunction("Raycast::DrawTile^2", (void *)Ray_DrawTile);
- engine->RegisterScriptFunction("Raycast::DrawOntoTile^2", (void *)Ray_DrawOntoTile);
- engine->RegisterScriptFunction("Raycast::SetNoClip^1", (void *)Ray_SetNoClip);
- engine->RegisterScriptFunction("Raycast::GetNoClip^0", (void *)Ray_GetNoClip);
- engine->RegisterScriptFunction("Raycast::GetSpriteScaleX^1", (void *)Ray_GetSpriteScaleX);
- engine->RegisterScriptFunction("Raycast::SetSpriteScaleX^2", (void *)Ray_SetSpriteScaleX);
- engine->RegisterScriptFunction("Raycast::GetSpriteScaleY^1", (void *)Ray_GetSpriteScaleY);
- engine->RegisterScriptFunction("Raycast::SetSpriteScaleY^2", (void *)Ray_SetSpriteScaleY);
- engine->RegisterScriptFunction("Raycast::GetSpriteBlendType^1", (void *)Ray_GetSpriteBlendType);
- engine->RegisterScriptFunction("Raycast::SetSpriteBlendType^2", (void *)Ray_SetSpriteBlendType);
-
-
- engine->RegisterScriptFunction("Raycast::SetFloorAt^3", (void *)Ray_SetFloorAt);
- engine->RegisterScriptFunction("Raycast::SetCeilingAt^3", (void *)Ray_SetCeilingAt);
- engine->RegisterScriptFunction("Raycast::GetCeilingAt^2", (void *)Ray_GetCeilingAt);
- engine->RegisterScriptFunction("Raycast::GetFloorAt^2", (void *)Ray_GetFloorAt);
- engine->RegisterScriptFunction("Raycast::GetLightingAt^2", (void *)Ray_GetLightingAt);
- engine->RegisterScriptFunction("Raycast::SetLightingAt^3", (void *)Ray_SetLightingAt);
- engine->RegisterScriptFunction("Raycast::GetWallHotspot^1", (void *)Ray_GetWallHotspot);
- engine->RegisterScriptFunction("Raycast::GetWallTexture^2", (void *)Ray_GetWallTexture);
- engine->RegisterScriptFunction("Raycast::GetWallSolid^2", (void *)Ray_GetWallSolid);
- engine->RegisterScriptFunction("Raycast::GetWallIgnoreLighting^2", (void *)Ray_GetWallIgnoreLighting);
- engine->RegisterScriptFunction("Raycast::GetWallAlpha^2", (void *)Ray_GetWallAlpha);
- engine->RegisterScriptFunction("Raycast::GetWallBlendType^2", (void *)Ray_GetWallBlendType);
- engine->RegisterScriptFunction("Raycast::SelectTile^3", (void *)Ray_SelectTile);
- engine->RegisterScriptFunction("Raycast::HasSeenTile^2", (void *)Ray_HasSeenTile);
-
- engine->RegisterScriptFunction("LensDistort::SetPos^2", (void *)SetLensPos);
- engine->RegisterScriptFunction("LensDistort::GetX^0", (void *)GetLensX);
- engine->RegisterScriptFunction("LensDistort::GetY^0", (void *)GetLensY);
- engine->RegisterScriptFunction("LensDistort::Set^1", (void *)SetLensDrawn);
- engine->RegisterScriptFunction("LensDistort::IsDrawn^0", (void *)GetLensDrawn);
- engine->RegisterScriptFunction("LensDistort::SetOffsetClamp^1", (void *)SetLensOffsetClamp);
- engine->RegisterScriptFunction("LensDistort::GetOffsetClamp^0", (void *)GetLensOffsetClamp);
- engine->RegisterScriptFunction("LensDistort::GetLevel^0", (void *)GetLensLevel);
- engine->RegisterScriptFunction("LensDistort::SetLevel^1", (void *)GetLensLevel);
- engine->RegisterScriptFunction("LensDistort::Initialize^6", (void *)LensInitialize);
-
- engine->RegisterScriptFunction("Translucence::CreateOverlay^8", (void *)CreateTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::DeleteOverlay^1", (void *)DeleteTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::Move^3", (void *)MoveTranslucentOverlay);
- engine->RegisterScriptFunction("Translucence::GetOverlayX^1", (void *)GetTranslucentOverlayX);
- engine->RegisterScriptFunction("Translucence::GetOverlayY^1", (void *)GetTranslucentOverlayY);
- engine->RegisterScriptFunction("Translucence::GetOverlaySprite^1", (void *)GetTranslucentOverlaySprite);
- engine->RegisterScriptFunction("Translucence::GetOverlayLevel^1", (void *)GetTranslucentOverlayLevel);
- engine->RegisterScriptFunction("Translucence::GetOverlayEnabled^1", (void *)GetTranslucentOverlayEnabled);
- engine->RegisterScriptFunction("Translucence::GetOverlayAlpha^1", (void *)GetTranslucentOverlayAlpha);
- engine->RegisterScriptFunction("Translucence::SetOverlayAlpha^2", (void *)SetTranslucentOverlayAlpha);
- engine->RegisterScriptFunction("Translucence::SetOverlayEnabled^2", (void *)SetTranslucentOverlayEnabled);
- engine->RegisterScriptFunction("Translucence::DrawTransSprite^6", (void *)DrawTransSprite);
-
- engine->RegisterScriptFunction("Starfield::GetOverscan^0", (void *)GetStarfieldOverscan);
- engine->RegisterScriptFunction("Starfield::SetOverscan^1", (void *)SetStarfieldOverscan);
- engine->RegisterScriptFunction("Starfield::GetOriginX^0", (void *)GetStarfieldOriginX);
- engine->RegisterScriptFunction("Starfield::GetOriginY^0", (void *)GetStarfieldOriginY);
- engine->RegisterScriptFunction("Starfield::SetDepthMultiplier^1", (void *)SetStarfieldDepthMultiplier);
- engine->RegisterScriptFunction("Starfield::GetDepthMultiplier^0", (void *)GetStarfieldDepthMultiplier);
- engine->RegisterScriptFunction("Starfield::GetMaxStars^0", (void *)GetStarfieldMaxStars);
- engine->RegisterScriptFunction("Starfield::SetStarSpriteScaleBoost^1", (void *)SetStarSpriteScaleBoost);
- engine->RegisterScriptFunction("Starfield::GetStarSpriteScaleBoost^0", (void *)GetStarSpriteScaleBoost);
- engine->RegisterScriptFunction("Starfield::SetStarMaxRadius^2", (void *)SetStarMaxRadius);
- engine->RegisterScriptFunction("Starfield::GetStarMaxRadius^0", (void *)GetStarMaxRadius);
- engine->RegisterScriptFunction("Starfield::GetStarX^1", (void *)GetStarX);
- engine->RegisterScriptFunction("Starfield::GetStarY^1", (void *)GetStarY);
- engine->RegisterScriptFunction("Starfield::GetStarZ^1", (void *)GetStarZ);
- engine->RegisterScriptFunction("Starfield::SetStarPosition^4", (void *)SetStarPosition);
- engine->RegisterScriptFunction("Starfield::RotateStar^4", (void *)RotateStar);
- engine->RegisterScriptFunction("Starfield::SetStarColor^2", (void *)SetStarColor);
- engine->RegisterScriptFunction("Starfield::GetStarColor^1", (void *)GetStarColor);
- engine->RegisterScriptFunction("Starfield::SetStarSprite^2", (void *)SetStarSprite);
- engine->RegisterScriptFunction("Starfield::GetStarSprite^1", (void *)GetStarSprite);
- engine->RegisterScriptFunction("Starfield::SetStarSpriteRange^3", (void *)SetStarSpriteRange);
- engine->RegisterScriptFunction("Starfield::Initialize^2", (void *)InitializeStars);
- engine->RegisterScriptFunction("Starfield::Iterate^1", (void *)IterateStars);
- engine->RegisterScriptFunction("Starfield::Draw^2", (void *)DrawStars);
- engine->RegisterScriptFunction("Starfield::SetOriginPoint^2", (void *)SetStarsOriginPoint);
-
- engine->RegisterScriptFunction("Plasma::DoFire^8", (void *)DoFire);
- engine->RegisterScriptFunction("Plasma::SetPlasmaType^5", (void *)SetPlasmaType);
- engine->RegisterScriptFunction("Plasma::ResetPlasmaSettings^0", (void *)ResetPlasmaSettings);
- engine->RegisterScriptFunction("Plasma::DrawPlasma^3", (void *)DrawPlasma);
- engine->RegisterScriptFunction("Plasma::SetRootType^1", (void *)SetPlasmaRootType);
- engine->RegisterScriptFunction("Plasma::GetRootType^0", (void *)GetPlasmaRootType);
-
- engine->RegisterScriptFunction("Reflections::Set^1", (void *)SetReflections);
- engine->RegisterScriptFunction("Reflections::IsReflecting^0", (void *)IsReflectionsOn);
- engine->RegisterScriptFunction("Reflections::SetCharacterReflected^2", (void *)SetCharacterReflected);
- engine->RegisterScriptFunction("Reflections::GetCharacterReflected^1", (void *)GetCharacterReflected);
- engine->RegisterScriptFunction("Reflections::SetObjectReflected^2", (void *)SetObjectReflected);
- engine->RegisterScriptFunction("Reflections::GetObjectReflected^1", (void *)GetObjectReflected);
- engine->RegisterScriptFunction("Reflections::ReplaceCharacterReflectionView^2", (void *)ReplaceCharacterReflectionView);
- engine->RegisterScriptFunction("Reflections::SetObjectReflectionIgnoreScaling^2", (void *)SetObjectReflectionIgnoreScaling);
- engine->RequestEventHook(AGSE_PRESCREENDRAW);
- engine->RequestEventHook(AGSE_PREGUIDRAW);
- engine->RequestEventHook(AGSE_POSTSCREENDRAW);
- engine->RequestEventHook(AGSE_SAVEGAME);
- engine->RequestEventHook(AGSE_RESTOREGAME);
- engine->RequestEventHook(AGSE_ENTERROOM);
- stars = new starstype [MAX_STARS];
- Starfield.maxstars = MAX_STARS;
- Starfield.depthmultiplier = 256;
- Starfield.speed = 0.5;
- Starfield.originx = 160;
- Starfield.originy = 100;
- Reflection.Characters = new charrefopt [engine->GetNumCharacters()]();
- lens = new LensDistort [LENS_WIDTH * LENS_WIDTH]();
- //PreMultiply_Alphas ();
- plasmaroottype = 0;
- Make_Sin_Lut();
- Init_Raycaster();
-}
-
-void AGSPalRender::AGS_EngineShutdown() {
- // no work to do here - but if we had created any dynamic sprites,
- // we should delete them here
- delete[] Reflection.Characters;
- delete[] Reflection.Objects;
- //QuitCleanup();
-}
-
-NumberPtr AGSPalRender::AGS_EngineOnEvent(int event, NumberPtr data) {
- if (event == AGSE_PRESCREENDRAW && clutslot > 0) {
- if (drawreflections) {
- int32 sh, sw = 0;
- engine->GetScreenDimensions(&sw, &sh, nullptr);
- reflectionmap = new long[sw * sh]();
- rcolormap = engine->CreateBlankBitmap(sw, sh, 8);
- ralphamap = engine->CreateBlankBitmap(sw, sh, 8);
- for (int i = 0; i < engine->GetNumCharacters(); i++) {
- if (Reflection.Characters[i].reflect == 0) continue;
- AGSCharacter *tempchar = engine->GetCharacter(i);
- if (tempchar->room != engine->GetCurrentRoom()) continue; //if character isn't even in the room, go to next iteration.
- int32 vx = tempchar->x;
- int32 vy = tempchar->y;
- engine->RoomToViewport(&vx, &vy);
- AGSViewFrame *vf = engine->GetViewFrame(tempchar->view + 1, tempchar->loop, tempchar->frame);
- int w = engine->GetSpriteWidth(vf->pic);
- int h = engine->GetSpriteHeight(vf->pic);
- vx = vx - (w / 2);
- int32 vxmax = vx + w;
- int32 vymax = vy + h;
- if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
- DrawReflections(i, 0);
- }
- for (int i = 0; i < engine->GetNumObjects(); i++) {
- if (Reflection.Objects[i].reflect == 0) continue;
- AGSObject *tempobj = engine->GetObject(i);
- if (!tempobj->on) continue;
- int32 vx = tempobj->x;
- int32 vy = tempobj->baseline - tempobj->y;
- engine->RoomToViewport(&vx, &vy);
- int32 w = engine->GetSpriteWidth(tempobj->num);
- int32 h = engine->GetSpriteHeight(tempobj->num);
- int32 vxmax = vx + w;
- int32 vymax = vy + h;
- if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
- DrawReflections(i, 1);
- }
- BITMAP *virtsc = engine->GetVirtualScreen();
- unsigned char **screenbuffer = engine->GetRawBitmapSurface(virtsc);
- unsigned char **colorbuffer = engine->GetRawBitmapSurface(rcolormap);
- unsigned char **alphabuffer = engine->GetRawBitmapSurface(ralphamap);
- for (int y = 0; y < sh; y++)
- for (int x = 0; x < sw; x++)
- screenbuffer[y][x] = Mix::MixColorAlpha(colorbuffer[y][x], screenbuffer[y][x], alphabuffer[y][x]);
- engine->ReleaseBitmapSurface(rcolormap);
- engine->ReleaseBitmapSurface(ralphamap);
- engine->ReleaseBitmapSurface(virtsc);
- engine->FreeBitmap(rcolormap);
- engine->FreeBitmap(ralphamap);
- delete [] reflectionmap;
- }
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 0) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 0) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_PREGUIDRAW && clutslot > 0) {
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 1) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 2) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_POSTSCREENDRAW && clutslot > 0) {
- int i = 0;
- if (LensOption.draw == 1 && LensOption.level == 3) DrawLens(LensOption.x, LensOption.y);
- while (i < MAX_OVERLAYS) {
- if (overlay[i].enabled && overlay[i].level == 2) {
- DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
- }
- i++;
- }
- if (LensOption.draw == 1 && LensOption.level == 4) DrawLens(LensOption.x, LensOption.y);
- }
- if (event == AGSE_SAVEGAME) {
- for (int i = 0; i < MAX_OVERLAYS; ++i) {
- engine->FWrite(&overlay[i].sprite, sizeof(int), data);
- engine->FWrite(&overlay[i].spritemask, sizeof(int), data);
- engine->FWrite(&overlay[i].x, sizeof(int), data);
- engine->FWrite(&overlay[i].y, sizeof(int), data);
- engine->FWrite(&overlay[i].level, sizeof(int), data);
- engine->FWrite(&overlay[i].trans, sizeof(int), data);
- engine->FWrite(&overlay[i].blendtype, sizeof(int), data);
- engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
- }
- engine->FWrite(&clutslot, sizeof(int), data);
- engine->FWrite(&drawreflections, sizeof(int), data);
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data);
- engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data);
- engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) {
- engine->FWrite(&sprite[j].x, sizeof(double), data);
- engine->FWrite(&sprite[j].y, sizeof(double), data);
- engine->FWrite(&sprite[j].texture, sizeof(int), data);
- engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data);
- engine->FWrite(&sprite[j].uDivW, sizeof(double), data);
- engine->FWrite(&sprite[j].uDivH, sizeof(double), data);
- engine->FWrite(&sprite[j].vMove, sizeof(double), data);
- engine->FWrite(&sprite[j].hMove, sizeof(double), data);
- engine->FWrite(&sprite[j].objectinteract, sizeof(char), data);
- engine->FWrite(&sprite[j].view, sizeof(int), data);
- engine->FWrite(&sprite[j].frame, sizeof(int), data);
- engine->FWrite(&sprite[j].angle, sizeof(int), data);
- }
- for (int j = 0; j < 256; ++j) {
- for (int k = 0; k < 4; ++k) {
- engine->FWrite(&wallData[j].texture[k], sizeof(int), data);
- engine->FWrite(&wallData[j].solid[k], sizeof(int), data);
- engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data);
- engine->FWrite(&wallData[j].alpha[k], sizeof(int), data);
- engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data);
- engine->FWrite(&wallData[j].mask[k], sizeof(int), data);
- }
- engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data);
- }
- engine->FWrite(&raycastOn, sizeof(bool), data);
- engine->FWrite(&heightmapOn, sizeof(bool), data);
- engine->FWrite(&posX, sizeof(double), data);
- engine->FWrite(&posY, sizeof(double), data);
- engine->FWrite(&dirX, sizeof(double), data);
- engine->FWrite(&dirY, sizeof(double), data);
- engine->FWrite(&planeX, sizeof(double), data);
- engine->FWrite(&planeY, sizeof(double), data);
- engine->FWrite(&moveSpeed, sizeof(double), data);
- engine->FWrite(&rotSpeed, sizeof(double), data);
- if (raycastOn) { //If the raycaster is active, we have additional data to save.
- for (int i = 0; i < mapWidth; ++i)
- for (int j = 0; j < mapHeight; ++j) {
- engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data);
- engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data);
- engine->FWrite(&ceilingMap [i][j], sizeof(int), data);
- engine->FWrite(&floorMap [i][j], sizeof(int), data);
- engine->FWrite(&heightMap [i][j], sizeof(int), data);
- }
- }
- engine->FWrite(&textureSlot, sizeof(int), data);
- engine->FWrite(&skybox, sizeof(int), data);
- engine->FWrite(&ambientlight, sizeof(int), data);
- }
- if (event == AGSE_RESTOREGAME) {
-
-
- for (int i = 0; i < MAX_OVERLAYS; ++i) {
- engine->FRead(&overlay[i].sprite, sizeof(int), data);
- engine->FRead(&overlay[i].spritemask, sizeof(int), data);
- engine->FRead(&overlay[i].x, sizeof(int), data);
- engine->FRead(&overlay[i].y, sizeof(int), data);
- engine->FRead(&overlay[i].level, sizeof(int), data);
- engine->FRead(&overlay[i].trans, sizeof(int), data);
- engine->FRead(&overlay[i].blendtype, sizeof(int), data);
- engine->FRead(&overlay[i].enabled, sizeof(bool), data);
- }
- engine->FRead(&clutslot, sizeof(int), data);
- engine->FRead(&drawreflections, sizeof(int), data);
- for (int j = 0; j < 256; ++j) {
- engine->FRead(&cycle_remap[j], sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Objective Palette, for palette mixing.
- engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data);
- engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data);
- engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Raycaster Sprite struct, 256 instances.
- engine->FRead(&sprite[j].x, sizeof(double), data);
- engine->FRead(&sprite[j].y, sizeof(double), data);
- engine->FRead(&sprite[j].texture, sizeof(int), data);
- engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data);
- engine->FRead(&sprite[j].uDivW, sizeof(double), data);
- engine->FRead(&sprite[j].uDivH, sizeof(double), data);
- engine->FRead(&sprite[j].vMove, sizeof(double), data);
- engine->FRead(&sprite[j].hMove, sizeof(double), data);
- engine->FRead(&sprite[j].objectinteract, sizeof(char), data);
- engine->FRead(&sprite[j].view, sizeof(int), data);
- engine->FRead(&sprite[j].frame, sizeof(int), data);
- engine->FRead(&sprite[j].angle, sizeof(int), data);
- }
- for (int j = 0; j < 256; ++j) { //Save Raycaster wall type data.
- for (int k = 0; k < 4; ++k) {
- engine->FRead(&wallData[j].texture[k], sizeof(int), data);
- engine->FRead(&wallData[j].solid[k], sizeof(int), data);
- engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data);
- engine->FRead(&wallData[j].alpha[k], sizeof(int), data);
- engine->FRead(&wallData[j].blendtype[k], sizeof(int), data);
- engine->FRead(&wallData[j].mask[k], sizeof(int), data);
- }
- engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data);
- }
- //Delete worldmap data if it exists.
- engine->FRead(&raycastOn, sizeof(bool), data);
- engine->FRead(&heightmapOn, sizeof(bool), data);
- engine->FRead(&posX, sizeof(double), data);
- engine->FRead(&posY, sizeof(double), data);
- engine->FRead(&dirX, sizeof(double), data);
- engine->FRead(&dirY, sizeof(double), data);
- engine->FRead(&planeX, sizeof(double), data);
- engine->FRead(&planeY, sizeof(double), data);
- engine->FRead(&moveSpeed, sizeof(double), data);
- engine->FRead(&rotSpeed, sizeof(double), data);
- if (raycastOn) { //If the raycaster is currently running, we have additional data to load.
- for (int i = 0; i < mapWidth; ++i) {
- for (int j = 0; j < mapHeight; ++j) {
- engine->FRead(&worldMap [i][j], sizeof(unsigned char), data);
- engine->FRead(&lightMap [i][j], sizeof(unsigned char), data);
- engine->FRead(&ceilingMap [i][j], sizeof(int), data);
- engine->FRead(&floorMap [i][j], sizeof(int), data);
- engine->FRead(&heightMap [i][j], sizeof(int), data);
- seenMap [i][j] = 0;
- }
- }
-
- //Reinitialize all the buffers and stuff.
-
- }
- engine->FRead(&textureSlot, sizeof(int), data);
- if (textureSlot) MakeTextures(textureSlot);
- engine->FRead(&skybox, sizeof(int), data);
- engine->FRead(&ambientlight, sizeof(int), data);
- LoadCLUT(clutslot);
- }
- if (event == AGSE_ENTERROOM) {
- ResetRemapping();
- delete[] Reflection.Objects;
- Reflection.Objects = new objrefopt [engine->GetNumObjects()]();
- }
- return 0;
-}
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ags/lib/allegro.h"
+#include "ags/plugins/ags_pal_render/ags_pal_render.h"
+#include "ags/plugins/ags_pal_render/pal_render.h"
+#include "ags/plugins/ags_pal_render/raycast.h"
+#include "ags/ags.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define MAX_OVERLAYS 128
+#define MAX_STARS 1024
+#define MAX_DEPTH 64
+
+#define PI (3.1415926535f)
+#define HALF_PI (0.5f * PI)
+#define TWO_PI (2.0f * PI)
+#define TWO_PI_INV (1.0f / TWO_PI)
+
+const float halfpi = (0.5f * PI);
+const float twopi = (2.0f * PI);
+const float twopi_inv = (1.0f / TWO_PI);
+const float pisquared = PI * PI;
+const float picubed = PI * PI * PI;
+
+IAGSEngine *engine;
+
+//unsigned char clut[256][256];
+unsigned char clut[65536];
+
+struct transoverlaytype {
+ int sprite;
+ int spritemask;
+ int blendtype;
+ int x;
+ int y;
+ int trans;
+ int level;
+ bool enabled;
+} overlay[MAX_OVERLAYS];
+
+int clutslot;
+int drawreflections;
+unsigned char cycle_remap [256];
+
+struct starstype {
+ float x;
+ float y;
+ float z;
+ unsigned char color;
+ long sprite;
+ int maxrad;
+ int scaleboost;
+};
+starstype *stars;
+
+struct starsoptions {
+ float speed;
+ int maxstars;
+ int depthmultiplier;
+ int originx;
+ int originy;
+ int overscan;
+} Starfield;
+long *reflectionmap;
+BITMAP *rcolormap;
+BITMAP *ralphamap;
+
+struct charrefopt {
+ char reflect;
+ int replaceview;
+};
+
+struct objrefopt {
+ char reflect;
+ char ignorescaling;
+};
+
+struct reflectionopt {
+ charrefopt *Characters;
+ objrefopt *Objects;
+ int blendslot;
+ int blendamount;
+} Reflection;
+
+int dummy;
+
+#define LENS_WIDTH 150
+
+struct LensDistort {
+ int xoffset;
+ int yoffset;
+};
+
+LensDistort *lens;
+struct LensOpt {
+ bool draw;
+ int lenswidth;
+ int lenszoom;
+ int level;
+ int x;
+ int y;
+ int clampoffset;
+} LensOption;
+
+const int alphamultiply [4096] = {
+//#include "alphamultiply.txt"
+};
+float rot_sine_LUT[360];
+float rot_cos_LUT[360];
+
+BITMAP *backgroundimage;
+
+PALSTRUCT objectivepal[256];
+int bgimgspr;
+
+void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) {
+ objectivepal[index].r = r;
+ objectivepal[index].b = b;
+ objectivepal[index].g = g;
+}
+
+int ReadObjectivePaletteR(unsigned char index) {
+ return objectivepal[index].r;
+}
+
+int ReadObjectivePaletteB(unsigned char index) {
+ return objectivepal[index].b;
+}
+int ReadObjectivePaletteG(unsigned char index) {
+ return objectivepal[index].g;
+}
+
+
+#define SQRT_MAGIC_F 0x5f3759df
+float q3sqrt(const float x) {
+ const float xhalf = 0.5f * x;
+
+ union { // get bits for floating value
+ float x;
+ int i;
+ } u;
+ u.x = x;
+ u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
+ return x * u.x * (1.5f - xhalf * u.x * u.x); // Newton step, repeating increases accuracy
+}
+
+void Make_Sin_Lut() {
+ for (int angle = 0; angle < 360; angle++) {
+ double rad = (angle * PI) / 180.0;
+ rot_sine_LUT [angle] = static_cast<float>(sin(rad));
+ rot_cos_LUT [angle] = static_cast<float>(cos(rad));
+ }
+}
+
+/*
+void PreMultiply_Alphas () //Ha ha, this isn't the kind of premultiplcation you're thinking of.
+{
+ for (int y=0;y<64;y++)
+ for (int x=0;x<64;x++)
+ alphamultiply [y*64+x] = y*x;
+}
+*/
+
+int GetModifiedBackgroundImage() {
+ return bgimgspr;
+}
+
+unsigned short root(unsigned short x) {
+ unsigned short a, b;
+ b = x;
+ a = x = 0x3f;
+ x = b / x;
+ a = x = (x + a) >> 1;
+ x = b / x;
+ a = x = (x + a) >> 1;
+ x = b / x;
+ x = (x + a) >> 1;
+ return (x);
+}
+
+
+float Hill(float x) {
+ const float a0 = 1.0f;
+ const float a2 = 2.0f / PI - 12.0f / (pisquared);
+ const float a3 = 16.0f / (picubed) - 4.0f / (pisquared);
+ const float xx = x * x;
+ const float xxx = xx * x;
+
+ return a0 + a2 * xx + a3 * xxx;
+}
+
+float FastSin(float x) {
+ // wrap x within [0, TWO_PI)
+ const float a = x * twopi_inv;
+ x -= static_cast<int>(a) * twopi;
+ if (x < 0.0f)
+ x += twopi;
+
+ // 4 pieces of hills
+ if (x < halfpi)
+ return Hill(halfpi - x);
+ else if (x < PI)
+ return Hill(x - halfpi);
+ else if (x < 3.0f * halfpi)
+ return -Hill(3.0f * halfpi - x);
+ else
+ return -Hill(x - 3.0f * halfpi);
+}
+
+float FastCos(float x) {
+ return FastSin(x + halfpi);
+}
+
+FLOAT_RETURN_TYPE AGSFastSin(SCRIPT_FLOAT(x)) {
+ INIT_SCRIPT_FLOAT(x);
+ x = FastSin(x);
+ RETURN_FLOAT(x);
+}
+
+FLOAT_RETURN_TYPE AGSFastCos(SCRIPT_FLOAT(x)) {
+ INIT_SCRIPT_FLOAT(x);
+ x = FastSin(x + halfpi);
+ RETURN_FLOAT(x);
+}
+
+
+void DrawLens(int ox, int oy) {
+ int32 sh, sw = 0;
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen.");
+ BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8);
+ unsigned char **vScreen = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite);
+ int radius = LensOption.lenswidth >> 1;
+ for (int y = 0; y < LensOption.lenswidth; y++) {
+ int ypos = y * LensOption.lenswidth;
+ for (int x = 0; x < LensOption.lenswidth; x++) {
+ int lenspos = ypos + x;
+ int coffx = lens[lenspos].xoffset;
+ int coffy = lens[lenspos].yoffset;
+ if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) {
+ lensarray[y][x] = vScreen[oy + coffy][ox + coffx];
+ //vScreen[oy+coffy][ox+coffx] = ABS(coffy);
+ }
+ }
+ }
+ /*
+ for (int y=0;y<LensOption.lenswidth;y++)
+ {
+ int ypos = y*LensOption.lenswidth;
+ for (int x=0;x<LensOption.lenswidth;x++)
+ {
+ if (oy+y > 0 && oy+y < sh && ox+x > 0 && ox+x < sw)
+ {
+ vScreen[oy+y][ox+x] = lensarray[y][x];
+ }
+ }
+ }
+ */
+ int radsq = radius * radius;
+ for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
+ int cysq = cy * cy;
+ for (int cx = -radius; cx <= radius; cx++) {
+ int cxsq = cx * cx;
+ int dx = cx + ox;
+ int dy = cy + oy;
+ if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) {
+ //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong");
+ vScreen[dy][dx] = lensarray[cy + radius][cx + radius];
+ }
+ }
+ }
+
+ engine->ReleaseBitmapSurface(lenswrite);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->FreeBitmap(lenswrite);
+}
+
+void SetLensPos(int x, int y) {
+ LensOption.x = x;
+ LensOption.y = y;
+}
+
+int GetLensX() {
+ return LensOption.x;
+}
+
+int GetLensY() {
+ return LensOption.y;
+}
+
+void SetLensDrawn(int toggle) {
+ if (toggle > 0) LensOption.draw = 1;
+ else LensOption.draw = 0;
+}
+
+int GetLensDrawn() {
+ return LensOption.draw;
+}
+
+void SetLensOffsetClamp(int clamp) {
+ if (clamp < 0) LensOption.clampoffset = LensOption.lenswidth;
+ else LensOption.clampoffset = clamp;
+}
+
+int GetLensOffsetClamp() {
+ return LensOption.clampoffset;
+}
+
+int GetLensLevel() {
+ return LensOption.level;
+}
+
+void SetLensLevel(int level) {
+ if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
+ else LensOption.level = level;
+}
+
+void LensInitialize(int width, int zoom, int lensx, int lensy, int level, int clamp = -1) {
+ int32 sw, sh, radius;
+ if (width < 1) engine->AbortGame("Invalid lens dimension!");
+ radius = width >> 1;
+ lens = new LensDistort [width * width]();
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ int radsq = radius * radius;
+ int zoomsq = zoom * zoom;
+ for (int y = 0; y < radius; y++) {
+ int ysq = y * y;
+ for (int x = 0; x < radius; x++) {
+ int lx, ly;
+ int xsq = x * x;
+ if ((xsq + ysq) < (radsq)) {
+ float shift = zoom / sqrt((float)(zoomsq - (xsq + ysq - radsq)));
+ lx = (int)(x * shift - x);
+ ly = (int)(y * shift - y);
+ } else {
+ lx = 0;
+ ly = 0;
+ }
+ lens[(radius - y)*width + (radius - x)].xoffset = lx;
+ lens[(radius - y)*width + (radius - x)].yoffset = ly;
+ lens[(radius + y)*width + (radius + x)].xoffset = -lx;
+ lens[(radius + y)*width + (radius + x)].yoffset = -ly;
+ lens[(radius + y)*width + (radius - x)].xoffset = lx;
+ lens[(radius + y)*width + (radius - x)].yoffset = -ly;
+ lens[(radius - y)*width + (radius + x)].xoffset = -lx;
+ lens[(radius - y)*width + (radius + x)].yoffset = ly;
+ }
+ }
+ LensOption.lenswidth = width;
+ LensOption.lenszoom = zoom;
+ if (clamp < 0) LensOption.clampoffset = width;
+ else LensOption.clampoffset = clamp;
+ LensOption.x = lensx;
+ LensOption.y = lensy;
+ if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level.");
+ else LensOption.level = level;
+}
+
+void ResetRemapping() {
+ for (int j = 0; j < 256; ++j) {
+ cycle_remap [j] = j;
+ }
+}
+
+#define MAX_PLASMA_COMPLEXITY 4
+int plasmatype[MAX_PLASMA_COMPLEXITY];
+int plasmadata [MAX_PLASMA_COMPLEXITY];
+int plasmadata2 [MAX_PLASMA_COMPLEXITY];
+int plasmadata3 [MAX_PLASMA_COMPLEXITY];
+int plasmaroottype;
+
+
+void SetPlasmaRootType(int real) {
+ if (real) plasmaroottype = 1;
+ else plasmaroottype = 0;
+}
+
+int GetPlasmaRootType() {
+ return plasmaroottype;
+}
+
+void SetPlasmaType(int component, int type, int data, int data2, int data3) {
+ if (component >= MAX_PLASMA_COMPLEXITY) engine->AbortGame("Plasma too complex!");
+ else {
+ plasmatype [component] = type;
+ plasmadata [component] = data;
+ plasmadata2[component] = data2;
+ plasmadata3[component] = data3;
+ }
+
+ //0 = None.
+ //1 = Horizontal Bars (data=width)
+ //2 = Vertical Bars (data=width)
+ //3 = Circle (data=x,data2=y,data3=width)
+ //4 = Diagonal Bars (data=width)
+}
+
+void ResetPlasmaSettings() {
+ int i = 0;
+ while (i < MAX_PLASMA_COMPLEXITY) {
+ plasmatype [i] = 0;
+ plasmadata [i] = 0;
+ plasmadata2[i] = 0;
+ plasmadata3[i] = 0;
+ i++;
+ }
+}
+
+void DrawPlasma(int slot, int palstart, int palend) {
+ BITMAP *plasmaspr = engine->GetSpriteGraphic(slot);
+ if (!plasmaspr) engine->AbortGame("Plasma: Not a sprite I can load.");
+ int32 w, h, basecol, range = 0;
+ if (palend > palstart) {
+ range = palend - palstart;
+ basecol = palstart;
+ } else {
+ range = palstart - palend;
+ basecol = palend;
+ }
+ engine->GetBitmapDimensions(plasmaspr, &w, &h, nullptr);
+ unsigned char **plasmarray = engine->GetRawBitmapSurface(plasmaspr);
+ double frange = range / 2.0;
+ int complex = 0;
+ int color = 0;
+ int i = 0;
+ while (i < MAX_PLASMA_COMPLEXITY) {
+ if (plasmatype[i] > 0) complex++;
+ i++;
+ }
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ color = 0;
+ for (int p = 0; p < MAX_PLASMA_COMPLEXITY; p++) {
+ if (plasmatype[p] == 1) { //1 = Horizontal Bars (data=width)
+ color += int(frange + (frange * FastSin(y / (float)plasmadata[p])));
+ } else if (plasmatype[p] == 2) { //2 = Vertical Bars (data=width)
+ color += int(frange + (frange * FastSin(x / (float)plasmadata[p])));
+ } else if (plasmatype[p] == 3) { //3 = Circle (data=x,data2=y,data3=width)
+ int cx, cy = 0;
+ cx = plasmadata [p];
+ cy = plasmadata2 [p];
+ if (plasmaroottype == 1) color += int(frange + (frange * FastSin(q3sqrt((float)((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
+ else color += int(frange + (frange * FastSin(root(((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p]))));
+ } else if (plasmatype[p] == 4) { //4 = Diagonal Bars (data=width)
+ color += int(frange + (frange * FastSin((x + y) / (float)plasmadata[p])));
+ }
+ }
+ if (color > 0 && complex > 0) color = color / complex;
+ plasmarray[y][x] = static_cast<unsigned char>(basecol + color);
+ }
+ }
+ engine->ReleaseBitmapSurface(plasmaspr);
+ engine->NotifySpriteUpdated(slot);
+}
+
+void DoFire(int spriteId, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) {
+ BITMAP *firespr = engine->GetSpriteGraphic(masksprite);
+ BITMAP *firecolorspr = engine->GetSpriteGraphic(spriteId);
+ BITMAP *seedspr;
+ int32 w, h = 0;
+ int range, basecol, dir = 0;
+ if (palend > palstart) {
+ range = palend - palstart;
+ basecol = palstart;
+ dir = 1;
+ } else {
+ range = palstart - palend;
+ basecol = palend;
+ dir = -1;
+ }
+ int divider = 256 / range;
+ engine->GetBitmapDimensions(firespr, &w, &h, nullptr);
+ unsigned char **fire = engine->GetRawBitmapSurface(firespr);
+ unsigned char **color = engine->GetRawBitmapSurface(firecolorspr);
+ int sparky = 0;
+ //srand(time(NULL));
+ for (int y = 0; y < h - 1; y++) {
+ if ((int)::AGS::g_vm->getRandomNumber(9) > 7 - windspeed) { //Wind right
+ for (int x = w - 1; x > 1; x--) {
+ fire[y][x] = fire[y][x - 1];
+ }
+ } else if ((int)::AGS::g_vm->getRandomNumber(9) > 7 + windspeed) { // wind left
+ for (int x = 0; x < w - 1; x++) {
+ fire[y][x] = fire[y][x + 1];
+ }
+ }
+ }
+ for (int x = 0; x < w; x++) {
+ sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
+ if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
+ ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
+ fire[h - sparky][x] = 255;
+ sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2));
+ if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff &&
+ ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7)
+ fire[h - sparky][x] = 0;
+ }
+ if (seed == 0) {
+ for (int x = 0; x < w; x++)
+ fire[h - 1][x] = 255;
+ for (int x = 0; x < w; x++)
+ fire[h - 2][x] = ::AGS::g_vm->getRandomNumber(255);
+ } else if (seed > 0) {
+ seedspr = engine->GetSpriteGraphic(seed);
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ engine->SetVirtualScreen(firespr);
+ engine->BlitBitmap(0, 0, seedspr, 1);
+ engine->SetVirtualScreen(virtsc);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->ReleaseBitmapSurface(seedspr);
+ engine->NotifySpriteUpdated(spriteId);
+ engine->NotifySpriteUpdated(masksprite);
+ }
+
+ for (int y = 0; y < h - 1; y++) {
+ for (int x = 0; x < w; x++) {
+ fire[y][x] =
+ ((fire[(y + 1) % h][(x - 1 + w) % w]
+ + fire[(y + 1) % h][(x) % w]
+ + fire[(y + 1) % h][(x + 1) % w]
+ + fire[(y + 2) % h][(x) % w])
+ * 100) / (400 + (100 - strength));
+ if (fire[y][x] < cutoff) fire[y][x] = 0;
+ //if (fire[y][x] ==255) color [y][x] = palend;
+ else color [y][x] = static_cast<unsigned char>(basecol + (fire[y][x] / divider) * dir);
+ }
+ }
+ engine->ReleaseBitmapSurface(firespr);
+ engine->ReleaseBitmapSurface(firecolorspr);
+ engine->NotifySpriteUpdated(spriteId);
+ engine->NotifySpriteUpdated(masksprite);
+}
+
+/*
+unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha)
+{
+ //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette ();
+ int i=0;
+ int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
+ int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
+ int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
+ //unsigned char ralpha = alpha>>2;
+ //unsigned char invralpha = 64-ralpha;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //int out_r = alphamultiply[(palette[fg].r>>1)][ralpha] + alphamultiply[(palette[bg].r>>1)][(invralpha)];
+ //int out_g = alphamultiply[(palette[fg].g)][ralpha] + alphamultiply[(palette[bg].g)][(invralpha)];
+ //int out_b = alphamultiply[(palette[fg].b>>1)][ralpha] + alphamultiply[(palette[bg].b>>1)][(invralpha)];
+ out_r = (out_r + 1 + (out_r >> 8)) >> 8;
+ out_g = (out_g + 1 + (out_g >> 8)) >> 8;
+ out_b = (out_b + 1 + (out_b >> 8)) >> 8;
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+
+unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha)
+{
+ //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette ();
+ int i=0;
+ int add_r,add_b,add_g = 0;
+ char ralpha = alpha>>2;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //add_r = (((palette[fg].r>>1) * (alpha))>>8);
+ //add_b = (((palette[fg].b>>1) * (alpha))>>8);
+ //add_g = (((palette[fg].g) * (alpha))>>8);
+ add_r = ((alphamultiply[(palette[fg].r>>1)*64+ralpha])>>6);
+ add_b = ((alphamultiply[(palette[fg].b>>1)*64+ralpha])>>6);
+ add_g = ((alphamultiply[(palette[fg].g )*64+ralpha])>>6);
+ int out_r = min(31,(palette[bg].r>>1) + add_r);
+ int out_g = min(63, palette[bg].g + add_g);
+ int out_b = min(31,(palette[bg].b>>1) + add_b);
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char (*clutp) = clut;
+ unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+*/
+unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b) {
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ int i = ((r << 11) | (g << 5) | b);
+ unsigned char *clutp = clut;
+ unsigned char result = *(clutp + i);
+ result = cycle_remap [result]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+}
+
+void CycleRemap(int start, int end) {
+ if (end > start) {
+ // Rotate left
+ int wraparound = cycle_remap [start];
+ for (; start < end; ++start) {
+ cycle_remap [start] = cycle_remap [start + 1];
+ }
+ cycle_remap [end] = wraparound;
+ } else if (end < start) {
+ // Rotate right
+ int wraparound = cycle_remap [start];
+ for (; start > end; --start) {
+ cycle_remap [start] = cycle_remap [start - 1];
+ }
+ cycle_remap [end] = wraparound;
+
+ }
+}
+
+unsigned char GetRemappedSlot(unsigned char slot) {
+ return cycle_remap [slot];
+}
+
+int LoadCLUT(int slot) {
+ if (engine->GetSpriteWidth(slot) != 256 || engine->GetSpriteHeight(slot) != 256) return 1;
+ BITMAP *clutimage = engine->GetSpriteGraphic(slot);
+ unsigned char **clutarray = engine->GetRawBitmapSurface(clutimage);
+ for (int y = 0; y < 256; y++) {
+ for (int x = 0; x < 256; x++) {
+ clut[y * 256 + x] = clutarray[y][x];
+ }
+ }
+ clutslot = slot;
+ engine->ReleaseBitmapSurface(clutimage);
+ return 0;
+}
+
+void SetReflections(int toggle) {
+ drawreflections = toggle;
+}
+
+int IsReflectionsOn() {
+ return drawreflections;
+}
+
+int GetLuminosityFromPalette(int slot) {
+ AGSColor *pal = engine->GetPalette();
+ int lum = (pal[slot].r +
+ pal[slot].r +
+ pal[slot].r +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].g +
+ pal[slot].b) >> 3;
+ return lum;
+}
+
+
+
+void SetStarsOriginPoint(int x, int y) {
+ Starfield.originx = x;
+ Starfield.originy = y;
+}
+void InitializeStars(int slot, int maxstars) {
+ int32 sw, sh = 0;
+ BITMAP *canvas = engine->GetSpriteGraphic(slot);
+ engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
+ Starfield.maxstars = maxstars;
+ Starfield.overscan = 20;
+ stars = new starstype [Starfield.maxstars];
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)(MAX_DEPTH);
+ stars[i].color = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 240);
+ stars[i].sprite = 0;
+ stars[i].maxrad = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 5);
+ }
+}
+
+void IterateStars(int slot) {
+ long sw, sh = 0;
+ sw = engine->GetSpriteWidth(slot);
+ sh = engine->GetSpriteHeight(slot);
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ stars[i].z -= Starfield.speed;
+ //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
+ float k = Starfield.depthmultiplier / stars[i].z;
+ int px = static_cast<int>(stars[i].x * k + Starfield.originx);
+ int py = static_cast<int>(stars[i].y * k + Starfield.originy);
+ if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)MAX_DEPTH;
+ //stars[i].color = (rand () %240);
+ }
+ }
+}
+int GetStarfieldOverscan() {
+ return Starfield.overscan;
+}
+void SetStarfieldOverscan(int overscan) {
+ Starfield.overscan = overscan;
+}
+
+int GetStarfieldOriginX() {
+ return Starfield.originx;
+}
+
+int GetStarfieldOriginY() {
+ return Starfield.originy;
+}
+
+void SetStarfieldDepthMultiplier(int multi) {
+ Starfield.depthmultiplier = multi;
+}
+
+int GetStarfieldDepthMultiplier() {
+ return Starfield.depthmultiplier;
+}
+
+int GetStarfieldMaxStars() {
+ return Starfield.maxstars;
+}
+
+void SetStarSpriteScaleBoost(int star, int boost) {
+ stars[star].scaleboost = boost;
+}
+
+int GetStarSpriteScaleBoost(int star) {
+ return stars[star].scaleboost;
+}
+
+void SetStarMaxRadius(int star, int radius) {
+ stars[star].maxrad = radius;
+}
+
+int GetStarMaxRadius(int star) {
+ return stars[star].maxrad;
+}
+
+void RotateStar(int star, int angle, int px, int py) {
+ float rsin = rot_sine_LUT[angle];
+ float rcos = rot_cos_LUT[angle];
+ float fPx = (float)px;
+ float fPy = (float)py;
+ float x1 = 0, y1 = 0, xRot = 0, yRot = 0;
+ int i = star;
+ x1 = stars[i].x;
+ y1 = stars[i].y;
+ xRot = fPx + rcos * (x1 - fPx) - rsin * (y1 - fPy);
+ yRot = fPy + rsin * (x1 - fPx) + rcos * (y1 - fPy);
+ stars[i].x = xRot;
+ stars[i].y = yRot;
+ i++;
+}
+
+FLOAT_RETURN_TYPE GetStarX(int i) {
+ float starx = (float)stars[i].x;
+ RETURN_FLOAT(starx);
+}
+
+FLOAT_RETURN_TYPE GetStarY(int i) {
+ float stary = (float)stars[i].y;
+ RETURN_FLOAT(stary);
+}
+
+FLOAT_RETURN_TYPE GetStarZ(int i) {
+ float starz = (float)stars[i].z;
+ RETURN_FLOAT(starz);
+}
+
+void SetStarPosition(int star, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), SCRIPT_FLOAT(z)) {
+ INIT_SCRIPT_FLOAT(x);
+ INIT_SCRIPT_FLOAT(y);
+ INIT_SCRIPT_FLOAT(z);
+ stars[star].x = x;
+ stars[star].y = y;
+ stars[star].z = z;
+}
+
+void SetStarColor(int star, unsigned char color) {
+ stars[star].color = color;
+}
+
+unsigned char GetStarColor(int star) {
+ return stars[star].color;
+}
+
+void SetStarSprite(int star, int slot) {
+ stars[star].sprite = slot;
+}
+
+int GetStarSprite(int star) {
+ return stars[star].sprite;
+}
+
+void SetStarSpriteRange(int start, int end, int slot) {
+ int sfix = start;
+ int efix = end;
+ if (start > Starfield.maxstars) sfix = Starfield.maxstars - 1;
+ if (end > Starfield.maxstars) efix = Starfield.maxstars;
+ for (int i = sfix; i < efix; i++)
+ stars[i].sprite = slot;
+}
+
+void DrawStars(int slot, int maskslot) {
+ int32 sw, sh = 0;
+ BITMAP *canvas = engine->GetSpriteGraphic(slot);
+ if (!canvas) engine->AbortGame("DrawStars: Can't load sprite slot.");
+ BITMAP *maskcanvas = engine->GetSpriteGraphic(maskslot);
+ if (!maskcanvas) engine->AbortGame("DrawStars: Can't load mask slot.");
+ engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr);
+ unsigned char **screenarray = engine->GetRawBitmapSurface(canvas);
+ unsigned char **maskarray = engine->GetRawBitmapSurface(maskcanvas);
+ for (int i = 0; i < Starfield.maxstars; i++) {
+ //stars[i].z-= 0.5;
+ //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH;
+ float k = (float)Starfield.depthmultiplier / stars[i].z;
+ int px = static_cast<int>(stars[i].x * k + Starfield.originx);
+ int py = static_cast<int>(stars[i].y * k + Starfield.originy);
+ if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) {
+ stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw;
+ if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw;
+ stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh;
+ if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh;
+ stars[i].z = (float)MAX_DEPTH;
+ //stars[i].color = (rand () %240);
+ } else if (stars[i].z > 0) {
+ int ivalue = (63 - (int)stars[i].z);
+ if (ivalue > 63) ivalue = 63;
+ else if (ivalue < 0) ivalue = 0;
+ unsigned char value = (unsigned char)(ivalue);
+ unsigned char maskcolor = value << 2;
+ if (stars[i].sprite > 0) {
+ BITMAP *origspr = engine->GetSpriteGraphic(stars[i].sprite);
+ int scale = (ivalue + 1) * 100 >> 6;
+ //int scale = 50;
+ if (scale < 1) scale = 1;
+ /*
+ if (scale != 100)
+ {
+ unsigned char** orig = engine->GetRawBitmapSurface (origspr);
+ int32 h1,h2,w1,w2=0;
+ double fw2,fh2;
+ engine->GetBitmapDimensions (origspr,&w1,&h1,NULL);
+ fh2 = h1 * (scale / 100.0);
+ fw2 = w1 * (scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ if (w2 < 1) w2 = 1;
+ if (h2 < 1) h2 = 1;
+ resizspr = engine->CreateBlankBitmap (w2,h2,8);
+ unsigned char** resized = engine->GetRawBitmapSurface (resizspr);
+ int x_ratio = (int)((w1<<16)/w2) +1;
+ int y_ratio = (int)((h1<<16)/h2) +1;
+ int x2, y2 ;
+ for (int i=0;i<h2;i++)
+ {
+ for (int j=0;j<w2;j++)
+ {
+ x2 = ((j*x_ratio)>>16) ;
+ y2 = ((i*y_ratio)>>16) ;
+ resized [i][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface (resizspr);
+ }
+ //resizspr = origspr;
+ int32 w,h=0;
+ engine->GetBitmapDimensions (resizspr,&w,&h,NULL);
+ unsigned char **imagemap = engine->GetRawBitmapSurface (resizspr);
+ int ox = px - (w>>1);
+ int oy = py - (h>>1);
+ for (int dy=0;dy<h;dy++)
+ {
+ for (int dx=0;dx<w;dx++)
+ {
+ int ex = ox+dx;
+ int ey = oy+dy;
+ if (ex < sw && ex >= 0 && ey < sh && ey >= 0)
+ {
+ if (maskcolor > maskarray [ey][ex] && imagemap[dy][dx] > 0)
+ {
+ maskarray [ey][ex] = maskcolor;
+ screenarray [ey][ex] = imagemap[dy][dx];
+ }
+ }
+ }
+ }
+ */
+
+ unsigned char **orig = engine->GetRawBitmapSurface(origspr);
+ int32 h1, h2, w1, w2 = 0;
+ double fw2, fh2;
+ engine->GetBitmapDimensions(origspr, &w1, &h1, nullptr);
+ fh2 = h1 * (scale / 100.0);
+ fw2 = w1 * (scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ if (w2 < 1) w2 = 1;
+ if (h2 < 1) h2 = 1;
+ int x_ratio = (int)((w1 << 16) / w2) + 1;
+ int y_ratio = (int)((h1 << 16) / h2) + 1;
+ int x2, y2 ;
+ int ox = px - (w2 >> 1);
+ int oy = py - (h2 >> 1);
+ for (int ii = 0; ii < h2; ii++) {
+ int temprzy = ii * y_ratio;
+ int ey = oy + ii;
+ for (int j = 0; j < w2; j++) {
+ x2 = ((j * x_ratio) >> 16);
+ y2 = ((temprzy) >> 16);
+ int ex = ox + j;
+ if (ex < sw && ex >= 0 && ey < sh && ey >= 0) {
+ if (maskcolor > maskarray [ey][ex] && orig[y2][x2] > 0) {
+ maskarray [ey][ex] = maskcolor;
+ screenarray [ey][ex] = orig[y2][x2];
+ }
+ }
+ //resized [ii][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface(origspr);
+ } else if (stars[i].sprite == 0) {
+ if (stars[i].maxrad == 1) {
+ if (px < sw && px >= 0 && py < sh && py >= 0) {
+ if (maskcolor > maskarray[py][px]) {
+ maskarray[py][px] = maskcolor;
+ screenarray[py][px] = stars[i].color;
+ }
+ }
+ } else {
+ int scale = ((((int)stars[i].z) * 100) / 63);
+ if (scale < 1) scale = 1;
+ int radius = (stars[i].maxrad * (100 - scale) / 100);
+ int radsq = radius * radius;
+ //unsigned char color = GetColor565 (value>>1,value,value>>1);
+ unsigned char color = stars[i].color;
+ for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask.
+ int cysq = cy * cy;
+ for (int cx = -radius; cx <= radius; cx++) {
+ int cxsq = cx * cx;
+ int dx = cx + px;
+ int dy = cy + py;
+ if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) {
+ if (maskcolor > maskarray [dy][dx]) {
+ maskarray [dy][dx] = maskcolor;
+ screenarray [dy][dx] = color;
+ }
+ }
+ }
+ }
+ /*
+ for(int cy=-radius; cy<=radius; cy++) //Draw a circle around the point, for the color.
+ {
+ int cysq = cy*cy;
+ for(int cx=-radius; cx<=radius; cx++)
+ {
+ int cxsq = cx*cx;
+ int dx = cx+px;
+ int dy = cy+py;
+ if((cxsq+cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0)
+ {
+ if (maskarray [dy][dx] == maskcolor)screenarray [dy][dx] = color;
+ }
+ }
+ }
+ */
+ }
+ }
+ }
+ }
+ engine->ReleaseBitmapSurface(canvas);
+ engine->ReleaseBitmapSurface(maskcanvas);
+ engine->NotifySpriteUpdated(slot);
+ engine->NotifySpriteUpdated(maskslot);
+}
+
+
+int CreateTranslucentOverlay(int id, int spriteId, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) {
+ BITMAP *testspr = engine->GetSpriteGraphic(spriteId);
+ if (testspr) overlay[id].sprite = spriteId;
+ else engine->AbortGame("CreateTranslucentOverlay: Invalid spriteId.");
+ engine->ReleaseBitmapSurface(testspr);
+ overlay[id].level = MAX(0, MIN(level, 4));
+ overlay[id].trans = MAX(0, MIN(alpha, 255));
+ overlay[id].spritemask = mask;
+ overlay[id].x = ox;
+ overlay[id].y = oy;
+ overlay[id].enabled = true;
+ overlay[id].blendtype = blendmode;
+ return 0;
+}
+
+int DeleteTranslucentOverlay(int id) {
+ overlay[id].enabled = false;
+ overlay[id].sprite = 0;
+ overlay[id].x = 0;
+ overlay[id].y = 0;
+ overlay[id].level = 0;
+ overlay[id].trans = 0;
+ return 0;
+}
+
+int MoveTranslucentOverlay(int id, int ox, int oy) {
+ overlay[id].x = ox;
+ overlay[id].y = oy;
+ return 0;
+}
+
+int GetTranslucentOverlayX(int id) {
+ return overlay[id].x;
+}
+
+int GetTranslucentOverlayY(int id) {
+ return overlay[id].y;
+}
+
+int GetTranslucentOverlaySprite(int id) {
+ return overlay[id].sprite;
+}
+
+int GetTranslucentOverlayLevel(int id) {
+ return overlay[id].level;
+}
+
+int GetTranslucentOverlayEnabled(int id) {
+ return overlay[id].enabled;
+}
+
+int GetTranslucentOverlayAlpha(int id) {
+ return overlay[id].trans;
+}
+
+int SetTranslucentOverlayAlpha(int id, int alpha) {
+ if (alpha >= 0 && alpha < 256)
+ overlay[id].trans = alpha;
+ else
+ engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected.");
+ return 0;
+}
+
+int SetTranslucentOverlayEnabled(int id, int toggle) {
+ if (toggle > 0)
+ overlay[id].enabled = true;
+ else
+ overlay[id].enabled = false;
+ return 0;
+}
+
+void SetCharacterReflected(int id, int refl) {
+ if (refl > 0) Reflection.Characters[id].reflect = 1;
+ else Reflection.Characters[id].reflect = 0;
+}
+
+void SetObjectReflected(int id, int refl) {
+ if (refl > 0)
+ Reflection.Objects[id].reflect = 1;
+ else
+ Reflection.Objects[id].reflect = 0;
+}
+
+int GetCharacterReflected(int id) {
+ return Reflection.Characters[id].reflect;
+}
+
+int GetObjectReflected(int id) {
+ return Reflection.Objects[id].reflect;
+}
+
+void ReplaceCharacterReflectionView(int id, int view) {
+ Reflection.Characters[id].replaceview = view - 1;
+}
+
+void SetObjectReflectionIgnoreScaling(int id, int wb) {
+ if (wb) Reflection.Objects[id].ignorescaling = 1;
+ else Reflection.Objects[id].ignorescaling = 0;
+}
+
+int DrawReflections(int id, int charobj = 0) {
+ int32 screenw, screenh;
+ int32 bgw, bgh;
+ engine->GetScreenDimensions(&screenw, &screenh, nullptr);
+ BITMAP *bgmask = engine->GetBackgroundScene(1);
+ if (bgmask == nullptr) return 1;
+ //BITMAP *virtsc = engine->GetVirtualScreen();
+ BITMAP *walkbehind = engine->GetRoomMask(MASK_WALKBEHIND);
+ //if (!virtsc) engine->AbortGame ("Can't load virtual screen.");
+ if (!walkbehind) engine->AbortGame("DrawRelfections: Can't load Walkbehind into memory.");
+ engine->GetBitmapDimensions(walkbehind, &bgw, &bgh, nullptr);
+ if (!bgmask) engine->AbortGame("DrawReflections: Can't load reflection mask.");
+ //unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc);
+ unsigned char **wbarray = engine->GetRawBitmapSurface(walkbehind);
+ unsigned char **maskarray = engine->GetRawBitmapSurface(bgmask);
+ //Initialize stuff
+ BITMAP *charsprite = nullptr;
+ BITMAP *charsprite2 = nullptr;
+ AGSCharacter *currchar = nullptr;
+ AGSObject *currobj;
+ int cox = 0, coy = 0, coz = 0;
+ int scale = 0;
+ //Get character, and their sprite.
+ if (charobj == 0) {
+ currchar = engine->GetCharacter(id);
+ /*int view = 0;
+ if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1;
+ else view = Reflection.Characters[id].replaceview;
+ */
+ AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame);
+ charsprite = engine->GetSpriteGraphic(vf->pic);
+ long scaling = currchar->flags & CHF_NOSCALING;
+ if (!scaling)scale = engine->GetAreaScaling(currchar->x, currchar->y);
+ else scale = 100;
+ cox = currchar->x;
+ coy = currchar->y;
+ coz = currchar->z;
+ } else if (charobj == 1) {
+ currobj = engine->GetObject(id);
+
+ charsprite = engine->GetSpriteGraphic(currobj->num);
+ if (Reflection.Objects[id].ignorescaling) scale = 100;
+ else scale = engine->GetAreaScaling(currobj->x, currobj->y);
+ cox = currobj->x;
+ if (currobj->baseline < 0) coy = currobj->y;
+ else coy = currobj->baseline;
+ coz = 0;
+ }
+ bool scaled = false;
+ int32 w, h;
+ engine->GetBitmapDimensions(charsprite, &w, &h, nullptr);
+ if (scale != 100) {
+ unsigned char **orig = engine->GetRawBitmapSurface(charsprite);
+ int h1, h2, w1, w2;
+ double fw2, fh2;
+ h1 = h;
+ w1 = w;
+ fh2 = h1 * ((double)scale / 100.0);
+ fw2 = w1 * ((double)scale / 100.0);
+ h2 = static_cast<int>(fh2);
+ w2 = static_cast<int>(fw2);
+ charsprite2 = engine->CreateBlankBitmap(w2, h2, 8);
+ unsigned char **resized = engine->GetRawBitmapSurface(charsprite2);
+ int x_ratio = (int)((w1 << 16) / w2) + 1;
+ int y_ratio = (int)((h1 << 16) / h2) + 1;
+ int x2, y2 ;
+ for (int i = 0; i < h2; i++) {
+ for (int j = 0; j < w2; j++) {
+ x2 = ((j * x_ratio) >> 16) ;
+ y2 = ((i * y_ratio) >> 16) ;
+ resized [i][j] = orig [y2][x2];
+ }
+ }
+ engine->ReleaseBitmapSurface(charsprite2);
+ scaled = true;
+ w = w2;
+ h = h2;
+ } else {
+ charsprite2 = charsprite;
+ }
+ int transamount = 0;
+ unsigned char **spritearray = engine->GetRawBitmapSurface(charsprite2);
+ unsigned char **charbuffer = engine->GetRawBitmapSurface(rcolormap);
+ unsigned char **alphaarray = engine->GetRawBitmapSurface(ralphamap);
+ int i = h - 1, j = 0;
+ int32 ox = cox;
+ if (charobj == 0) ox = ox - (w / 2);
+ int32 oy = coy + coz - 1;
+ engine->RoomToViewport(&ox, &oy);
+ int yoffset = 0;
+ int translevel = 7;
+ //bool dither = false;
+ //bool dodither = false;
+ int counter = 0;
+ int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0));
+ int delay = screenh / rowcount;
+ int *obst;
+ int flipped = 0;
+ if (charobj == 0) {
+ int (*sfGetGameParameter)(int, int, int, int);
+ sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter"));
+ flipped = sfGetGameParameter(13, currchar->view + 1, currchar->loop, currchar->frame);
+ } else flipped = 0;
+ obst = new int [w];
+ for (int k = 0; k < w; k++) {
+ obst[k] = 0;
+ }
+ while (i > 0) {
+ //if ((counter == delay/2-1 || counter == delay-1) && yoffset < 36) dodither = (!dodither);
+ if (counter == delay) {
+ counter = 0;
+ if (translevel > 0) translevel--;
+ } else counter++;
+ yoffset++;
+ while (j < w) {
+ int xoffset;
+ if (flipped == 1) xoffset = w - j - 1;
+ else xoffset = j;
+ int32 rx = ox + xoffset, ry = oy + yoffset;
+ int wbb = 0;
+ engine->ViewportToRoom(&rx, &ry);
+ if (ry > 0 && ry < bgh && rx > 0 && rx < bgw) {
+ if (wbarray [ry][rx] > 0) {
+ wbb = engine->GetWalkbehindBaseline(wbarray[ry][rx]);
+ }
+ if (maskarray[ry][rx] == 21) obst[j] = 1;
+ }
+
+ //dither = (!dither);
+ transamount = 32 * translevel;
+ if (spritearray [i][j] != 0 && oy + yoffset < screenh && ox + xoffset < screenw && oy + yoffset >= 0 && ox + xoffset >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg.
+ if (wbb < ry && obst[j] == 0 && (oy > reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))])) {
+ //charbuffer[oy+yoffset][ox+xoffset] = MixColorAlpha (spritearray [i][j],charbuffer[oy+yoffset][ox+xoffset],transamount);
+ charbuffer [oy + yoffset][ox + xoffset] = spritearray [i][j];
+ alphaarray [oy + yoffset][ox + xoffset] = transamount;
+ reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))] = oy;
+ }
+ }
+ j++;
+ }
+ //if (w % 2 == 0) dither = (!dither);
+ i--;
+ j = 0;
+ }
+
+ delete [] obst;
+ if (scaled == true)engine->FreeBitmap(charsprite2);
+ engine->ReleaseBitmapSurface(charsprite);
+ //engine->ReleaseBitmapSurface (virtsc);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(bgmask);
+ engine->ReleaseBitmapSurface(walkbehind);
+ engine->ReleaseBitmapSurface(rcolormap);
+ engine->ReleaseBitmapSurface(ralphamap);
+ engine->MarkRegionDirty(ox, oy, ox + w, oy + h);
+ return 0;
+}
+
+
+int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) {
+ BITMAP *maskspr = nullptr;
+ unsigned char **maskarray = nullptr;
+ if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
+ if (!maskspr && mask > 0) {
+ char maskerr [100];
+ snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
+ engine->AbortGame(maskerr);
+ }
+ // Get a reference to the screen we'll draw onto
+ BITMAP *bgspr = engine->GetSpriteGraphic(bg);
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
+ if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background");
+ //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
+ if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay spriteId into memory.");
+ // Get its surface
+ int32 sprw, sprh, coldepth;
+ int32 bgw, bgh;
+ engine->GetBitmapDimensions(bgspr, &bgw, &bgh, &coldepth);
+ engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
+
+ unsigned char **bgarray = engine->GetRawBitmapSurface(bgspr);
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
+ if (mask > 0) maskarray = engine->GetRawBitmapSurface(maskspr);
+ int tloffset = 255 - translevel;
+ int x = 0;
+ int y = 0;
+ //int transamount = 256 * translevel; //old
+ while (y < sprh) {
+ while (x < sprw) {
+ if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the bg.
+ if (mask > 0) {
+ translevel = MAX(maskarray [y][x] - tloffset, 0);
+ }
+ //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
+ if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
+ else if (blendmode == 1) spritearray[y][x] = Mix::MixColorAdditive(spritearray [y][x], bgarray[y][x], translevel, use_objpal);
+ }
+ x++;
+ }
+ x = 0;
+ y++;
+ }
+
+ // Release the screen so that the engine can continue
+ engine->ReleaseBitmapSurface(bgspr);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(spritespr);
+ engine->NotifySpriteUpdated(spriteId);
+ return 0;
+}
+
+int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) {
+ if (translevel == 0) return 0;
+ BITMAP *maskspr = nullptr;
+ unsigned char **maskarray = nullptr;
+ // Get a reference to the screen we'll draw onto
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ BITMAP *spritespr = engine->GetSpriteGraphic(spriteId);
+ if (mask > 0) maskspr = engine->GetSpriteGraphic(mask);
+ if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen.");
+ //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory.");
+ if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay spriteId into memory.");
+ // Get its surface
+ int32 sprw, sprh, coldepth;
+ int32 screenw, screenh;
+ engine->GetScreenDimensions(&screenw, &screenh, &coldepth);
+ engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth);
+ unsigned char **charbuffer = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr);
+ if (mask > 0) {
+ if (!maskspr && mask > 0) {
+ char maskerr [100];
+ snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask);
+ engine->AbortGame(maskerr);
+ }
+ maskarray = engine->GetRawBitmapSurface(maskspr);
+ }
+ int tloffset = 255 - translevel;
+ int x = 0;
+ int y = 0;
+ //int transamount = 256 * translevel; //old
+ while (y < sprh) {
+ while (x < sprw) {
+ if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the screen.
+ //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old
+ if (mask > 0) {
+ translevel = MAX(maskarray [y][x] - tloffset, 0);
+ }
+ if (blendmode == 0) {
+ if (translevel == 255) {
+ charbuffer[y + oy][x + ox] = spritearray [y][x];
+ } else charbuffer[y + oy][x + ox] = Mix::MixColorAlpha(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
+ } else if (blendmode == 1) charbuffer[y + oy][x + ox] = Mix::MixColorAdditive(spritearray [y][x], charbuffer[y + oy][x + ox], translevel);
+ }
+ x++;
+ }
+ x = 0;
+ y++;
+ }
+
+ // Release the screen so that the engine can continue
+ long dirtywidth = ox + sprw;
+ if (dirtywidth > screenw) dirtywidth = screenw - 1;
+ long dirtyheight = oy + sprh;
+ if (dirtyheight > screenh) dirtywidth = screenh - 1;
+ engine->ReleaseBitmapSurface(virtsc);
+ //engine->ReleaseBitmapSurface (clutspr);
+ engine->ReleaseBitmapSurface(spritespr);
+ if (mask > 0) engine->ReleaseBitmapSurface(maskspr);
+ engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+
+AGSPalRender::AGSPalRender() : DLL() {
+ DLL_METHOD(AGS_GetPluginName);
+ DLL_METHOD(AGS_EngineStartup);
+ DLL_METHOD(AGS_EngineShutdown);
+ DLL_METHOD(AGS_EngineOnEvent);
+}
+
+const char *AGSPalRender::AGS_GetPluginName() {
+ return "PALgorithms Translucent Overlay Renderer";
+}
+
+void AGSPalRender::AGS_EngineStartup(IAGSEngine *lpEngine) {
+ engine = lpEngine;
+
+ // Make sure it's got the version with the features we need
+ if (engine->version < 3) {
+ engine->AbortGame("Engine interface is too old, need newer version of AGS.");
+ }
+ engine->RegisterScriptFunction("PALInternal::LoadCLUT^1", (void *)LoadCLUT);
+ engine->RegisterScriptFunction("PALInternal::CycleRemap^2", (void *)CycleRemap);
+ engine->RegisterScriptFunction("PALInternal::GetColor565^3", (void *)GetColor565);
+ engine->RegisterScriptFunction("PALInternal::GetLuminosityFromPalette^1", (void *)GetLuminosityFromPalette);
+ engine->RegisterScriptFunction("PALInternal::FastSin^1", (void *)AGSFastSin);
+ engine->RegisterScriptFunction("PALInternal::FastCos^1", (void *)AGSFastCos);
+ engine->RegisterScriptFunction("PALInternal::FastRoot^1", (void *)root);
+ engine->RegisterScriptFunction("PALInternal::GetRemappedSlot^1", (void *)GetRemappedSlot);
+ engine->RegisterScriptFunction("PALInternal::ResetRemapping^0", (void *)ResetRemapping);
+ engine->RegisterScriptFunction("PALInternal::GetModifiedBackgroundImage", (void *)GetModifiedBackgroundImage);
+ engine->RegisterScriptFunction("PALInternal::WriteObjectivePalette^4", (void *)WriteObjectivePalette);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteR^1", (void *)ReadObjectivePaletteR);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteB^1", (void *)ReadObjectivePaletteB);
+ engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteG^1", (void *)ReadObjectivePaletteG);
+
+ engine->RegisterScriptFunction("Raycast::Render^1", (void *)Raycast_Render);
+ engine->RegisterScriptFunction("Raycast::LoadMap^4", (void *)LoadMap);
+ engine->RegisterScriptFunction("Raycast::Initialize", (void *)Init_Raycaster);
+ engine->RegisterScriptFunction("Raycast::MakeTextures^1", (void *)MakeTextures);
+ engine->RegisterScriptFunction("Raycast::MoveForward^0", (void *)MoveForward);
+ engine->RegisterScriptFunction("Raycast::MoveBackward^0", (void *)MoveBackward);
+ engine->RegisterScriptFunction("Raycast::RotateLeft^0", (void *)RotateLeft);
+ engine->RegisterScriptFunction("Raycast::RotateRight^0", (void *)RotateRight);
+ engine->RegisterScriptFunction("Raycast::SetCameraPosition^2", (void *)Ray_SetPlayerPosition);
+ engine->RegisterScriptFunction("Raycast::GetCameraX^0", (void *)Ray_GetPlayerX);
+ engine->RegisterScriptFunction("Raycast::GetCameraY^0", (void *)Ray_GetPlayerY);
+ engine->RegisterScriptFunction("Raycast::GetCameraAngle^0", (void *)Ray_GetPlayerAngle);
+ engine->RegisterScriptFunction("Raycast::SetCameraAngle^1", (void *)Ray_SetPlayerAngle);
+ engine->RegisterScriptFunction("Raycast::InitSprite^9", (void *)Ray_InitSprite);
+ engine->RegisterScriptFunction("Raycast::UnloadEngine^0", (void *)QuitCleanup);
+ engine->RegisterScriptFunction("Raycast::GetHotspotAtXY^2", (void *)Ray_GetHotspotAt);
+ engine->RegisterScriptFunction("Raycast::GetObjectAtXY^2", (void *)Ray_GetObjectAt);
+ engine->RegisterScriptFunction("Raycast::SetSpriteInteractObj^2", (void *)Ray_SetSpriteInteractObj);
+ engine->RegisterScriptFunction("Raycast::GetSpriteInteractObj^1", (void *)Ray_GetSpriteInteractObj);
+ engine->RegisterScriptFunction("Raycast::SetSpritePosition^3", (void *)Ray_SetSpritePosition);
+ engine->RegisterScriptFunction("Raycast::SetSpriteVertOffset^2", (void *)Ray_SetSpriteVertOffset);
+ engine->RegisterScriptFunction("Raycast::GetSpriteVertOffset^1", (void *)Ray_GetSpriteVertOffset);
+ engine->RegisterScriptFunction("Raycast::GetSpriteX^1", (void *)Ray_GetSpriteX);
+ engine->RegisterScriptFunction("Raycast::GetSpriteY^1", (void *)Ray_GetSpriteY);
+ engine->RegisterScriptFunction("Raycast::SetWallHotspot^2", (void *)Ray_SetWallHotspot);
+ engine->RegisterScriptFunction("Raycast::SetWallTextures^5", (void *)Ray_SetWallTextures);
+ engine->RegisterScriptFunction("Raycast::SetWallSolid^5", (void *)Ray_SetWallSolid);
+ engine->RegisterScriptFunction("Raycast::SetWallIgnoreLighting^5", (void *)Ray_SetWallIgnoreLighting);
+ engine->RegisterScriptFunction("Raycast::SetWallAlpha^5", (void *)Ray_SetWallAlpha);
+ engine->RegisterScriptFunction("Raycast::SetWallBlendType^5", (void *)Ray_SetWallBlendType);
+ engine->RegisterScriptFunction("Raycast::GetMoveSpeed^0", (void *)Ray_GetMoveSpeed);
+ engine->RegisterScriptFunction("Raycast::SetMoveSpeed^1", (void *)Ray_SetMoveSpeed);
+ engine->RegisterScriptFunction("Raycast::GetRotSpeed^0", (void *)Ray_GetRotSpeed);
+ engine->RegisterScriptFunction("Raycast::SetRotSpeed^1", (void *)Ray_SetRotSpeed);
+ engine->RegisterScriptFunction("Raycast::GetWallAt^2", (void *)Ray_GetWallAt);
+ engine->RegisterScriptFunction("Raycast::GetLightAt^2", (void *)Ray_GetLightAt);
+ engine->RegisterScriptFunction("Raycast::SetLightAt^3", (void *)Ray_SetLightAt);
+ engine->RegisterScriptFunction("Raycast::SetWallAt^3", (void *)Ray_SetWallAt);
+ engine->RegisterScriptFunction("Raycast::SetPlaneY^1", (void *)Ray_SetPlaneY);
+ engine->RegisterScriptFunction("Raycast::GetDistanceAt^2", (void *)Ray_GetDistanceAt);
+ engine->RegisterScriptFunction("Raycast::GetSpriteAngle^1", (void *)Ray_GetSpriteAngle);
+ engine->RegisterScriptFunction("Raycast::SetSpriteAngle^2", (void *)Ray_SetSpriteAngle);
+ engine->RegisterScriptFunction("Raycast::SetSpriteView^2", (void *)Ray_SetSpriteView);
+ engine->RegisterScriptFunction("Raycast::GetSpriteView^1", (void *)Ray_GetSpriteView);
+ engine->RegisterScriptFunction("Raycast::SetSpriteFrame^2", (void *)Ray_SetSpriteFrame);
+ engine->RegisterScriptFunction("Raycast::GetSpriteFrame^1", (void *)Ray_GetSpriteFrame);
+ engine->RegisterScriptFunction("Raycast::SetSpritePic^2", (void *)Ray_SetSpritePic);
+ engine->RegisterScriptFunction("Raycast::GetSpritePic^1", (void *)Ray_GetSpritePic);
+ engine->RegisterScriptFunction("Raycast::SetSkyBox^1", (void *)Ray_SetSkyBox);
+ engine->RegisterScriptFunction("Raycast::SetSpriteAlpha^2", (void *)Ray_SetSpriteAlpha);
+ engine->RegisterScriptFunction("Raycast::GetSpriteAlpha^1", (void *)Ray_GetSpriteAlpha);
+ engine->RegisterScriptFunction("Raycast::GetSkyBox^1", (void *)Ray_GetSkyBox);
+ engine->RegisterScriptFunction("Raycast::SetAmbientLight^1", (void *)Ray_SetAmbientLight);
+ engine->RegisterScriptFunction("Raycast::SetAmbientColor^2", (void *)Ray_SetAmbientColor);
+ engine->RegisterScriptFunction("Raycast::GetAmbientLight^0", (void *)Ray_GetAmbientLight);
+ engine->RegisterScriptFunction("Raycast::GetAmbientWeight^0", (void *)Ray_GetAmbientWeight);
+ engine->RegisterScriptFunction("Raycast::GetTileX_At^2", (void *)Ray_GetTileX_At);
+ engine->RegisterScriptFunction("Raycast::GetTileY_At^2", (void *)Ray_GetTileY_At);
+ engine->RegisterScriptFunction("Raycast::DrawTile^2", (void *)Ray_DrawTile);
+ engine->RegisterScriptFunction("Raycast::DrawOntoTile^2", (void *)Ray_DrawOntoTile);
+ engine->RegisterScriptFunction("Raycast::SetNoClip^1", (void *)Ray_SetNoClip);
+ engine->RegisterScriptFunction("Raycast::GetNoClip^0", (void *)Ray_GetNoClip);
+ engine->RegisterScriptFunction("Raycast::GetSpriteScaleX^1", (void *)Ray_GetSpriteScaleX);
+ engine->RegisterScriptFunction("Raycast::SetSpriteScaleX^2", (void *)Ray_SetSpriteScaleX);
+ engine->RegisterScriptFunction("Raycast::GetSpriteScaleY^1", (void *)Ray_GetSpriteScaleY);
+ engine->RegisterScriptFunction("Raycast::SetSpriteScaleY^2", (void *)Ray_SetSpriteScaleY);
+ engine->RegisterScriptFunction("Raycast::GetSpriteBlendType^1", (void *)Ray_GetSpriteBlendType);
+ engine->RegisterScriptFunction("Raycast::SetSpriteBlendType^2", (void *)Ray_SetSpriteBlendType);
+
+
+ engine->RegisterScriptFunction("Raycast::SetFloorAt^3", (void *)Ray_SetFloorAt);
+ engine->RegisterScriptFunction("Raycast::SetCeilingAt^3", (void *)Ray_SetCeilingAt);
+ engine->RegisterScriptFunction("Raycast::GetCeilingAt^2", (void *)Ray_GetCeilingAt);
+ engine->RegisterScriptFunction("Raycast::GetFloorAt^2", (void *)Ray_GetFloorAt);
+ engine->RegisterScriptFunction("Raycast::GetLightingAt^2", (void *)Ray_GetLightingAt);
+ engine->RegisterScriptFunction("Raycast::SetLightingAt^3", (void *)Ray_SetLightingAt);
+ engine->RegisterScriptFunction("Raycast::GetWallHotspot^1", (void *)Ray_GetWallHotspot);
+ engine->RegisterScriptFunction("Raycast::GetWallTexture^2", (void *)Ray_GetWallTexture);
+ engine->RegisterScriptFunction("Raycast::GetWallSolid^2", (void *)Ray_GetWallSolid);
+ engine->RegisterScriptFunction("Raycast::GetWallIgnoreLighting^2", (void *)Ray_GetWallIgnoreLighting);
+ engine->RegisterScriptFunction("Raycast::GetWallAlpha^2", (void *)Ray_GetWallAlpha);
+ engine->RegisterScriptFunction("Raycast::GetWallBlendType^2", (void *)Ray_GetWallBlendType);
+ engine->RegisterScriptFunction("Raycast::SelectTile^3", (void *)Ray_SelectTile);
+ engine->RegisterScriptFunction("Raycast::HasSeenTile^2", (void *)Ray_HasSeenTile);
+
+ engine->RegisterScriptFunction("LensDistort::SetPos^2", (void *)SetLensPos);
+ engine->RegisterScriptFunction("LensDistort::GetX^0", (void *)GetLensX);
+ engine->RegisterScriptFunction("LensDistort::GetY^0", (void *)GetLensY);
+ engine->RegisterScriptFunction("LensDistort::Set^1", (void *)SetLensDrawn);
+ engine->RegisterScriptFunction("LensDistort::IsDrawn^0", (void *)GetLensDrawn);
+ engine->RegisterScriptFunction("LensDistort::SetOffsetClamp^1", (void *)SetLensOffsetClamp);
+ engine->RegisterScriptFunction("LensDistort::GetOffsetClamp^0", (void *)GetLensOffsetClamp);
+ engine->RegisterScriptFunction("LensDistort::GetLevel^0", (void *)GetLensLevel);
+ engine->RegisterScriptFunction("LensDistort::SetLevel^1", (void *)GetLensLevel);
+ engine->RegisterScriptFunction("LensDistort::Initialize^6", (void *)LensInitialize);
+
+ engine->RegisterScriptFunction("Translucence::CreateOverlay^8", (void *)CreateTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::DeleteOverlay^1", (void *)DeleteTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::Move^3", (void *)MoveTranslucentOverlay);
+ engine->RegisterScriptFunction("Translucence::GetOverlayX^1", (void *)GetTranslucentOverlayX);
+ engine->RegisterScriptFunction("Translucence::GetOverlayY^1", (void *)GetTranslucentOverlayY);
+ engine->RegisterScriptFunction("Translucence::GetOverlaySprite^1", (void *)GetTranslucentOverlaySprite);
+ engine->RegisterScriptFunction("Translucence::GetOverlayLevel^1", (void *)GetTranslucentOverlayLevel);
+ engine->RegisterScriptFunction("Translucence::GetOverlayEnabled^1", (void *)GetTranslucentOverlayEnabled);
+ engine->RegisterScriptFunction("Translucence::GetOverlayAlpha^1", (void *)GetTranslucentOverlayAlpha);
+ engine->RegisterScriptFunction("Translucence::SetOverlayAlpha^2", (void *)SetTranslucentOverlayAlpha);
+ engine->RegisterScriptFunction("Translucence::SetOverlayEnabled^2", (void *)SetTranslucentOverlayEnabled);
+ engine->RegisterScriptFunction("Translucence::DrawTransSprite^6", (void *)DrawTransSprite);
+
+ engine->RegisterScriptFunction("Starfield::GetOverscan^0", (void *)GetStarfieldOverscan);
+ engine->RegisterScriptFunction("Starfield::SetOverscan^1", (void *)SetStarfieldOverscan);
+ engine->RegisterScriptFunction("Starfield::GetOriginX^0", (void *)GetStarfieldOriginX);
+ engine->RegisterScriptFunction("Starfield::GetOriginY^0", (void *)GetStarfieldOriginY);
+ engine->RegisterScriptFunction("Starfield::SetDepthMultiplier^1", (void *)SetStarfieldDepthMultiplier);
+ engine->RegisterScriptFunction("Starfield::GetDepthMultiplier^0", (void *)GetStarfieldDepthMultiplier);
+ engine->RegisterScriptFunction("Starfield::GetMaxStars^0", (void *)GetStarfieldMaxStars);
+ engine->RegisterScriptFunction("Starfield::SetStarSpriteScaleBoost^1", (void *)SetStarSpriteScaleBoost);
+ engine->RegisterScriptFunction("Starfield::GetStarSpriteScaleBoost^0", (void *)GetStarSpriteScaleBoost);
+ engine->RegisterScriptFunction("Starfield::SetStarMaxRadius^2", (void *)SetStarMaxRadius);
+ engine->RegisterScriptFunction("Starfield::GetStarMaxRadius^0", (void *)GetStarMaxRadius);
+ engine->RegisterScriptFunction("Starfield::GetStarX^1", (void *)GetStarX);
+ engine->RegisterScriptFunction("Starfield::GetStarY^1", (void *)GetStarY);
+ engine->RegisterScriptFunction("Starfield::GetStarZ^1", (void *)GetStarZ);
+ engine->RegisterScriptFunction("Starfield::SetStarPosition^4", (void *)SetStarPosition);
+ engine->RegisterScriptFunction("Starfield::RotateStar^4", (void *)RotateStar);
+ engine->RegisterScriptFunction("Starfield::SetStarColor^2", (void *)SetStarColor);
+ engine->RegisterScriptFunction("Starfield::GetStarColor^1", (void *)GetStarColor);
+ engine->RegisterScriptFunction("Starfield::SetStarSprite^2", (void *)SetStarSprite);
+ engine->RegisterScriptFunction("Starfield::GetStarSprite^1", (void *)GetStarSprite);
+ engine->RegisterScriptFunction("Starfield::SetStarSpriteRange^3", (void *)SetStarSpriteRange);
+ engine->RegisterScriptFunction("Starfield::Initialize^2", (void *)InitializeStars);
+ engine->RegisterScriptFunction("Starfield::Iterate^1", (void *)IterateStars);
+ engine->RegisterScriptFunction("Starfield::Draw^2", (void *)DrawStars);
+ engine->RegisterScriptFunction("Starfield::SetOriginPoint^2", (void *)SetStarsOriginPoint);
+
+ engine->RegisterScriptFunction("Plasma::DoFire^8", (void *)DoFire);
+ engine->RegisterScriptFunction("Plasma::SetPlasmaType^5", (void *)SetPlasmaType);
+ engine->RegisterScriptFunction("Plasma::ResetPlasmaSettings^0", (void *)ResetPlasmaSettings);
+ engine->RegisterScriptFunction("Plasma::DrawPlasma^3", (void *)DrawPlasma);
+ engine->RegisterScriptFunction("Plasma::SetRootType^1", (void *)SetPlasmaRootType);
+ engine->RegisterScriptFunction("Plasma::GetRootType^0", (void *)GetPlasmaRootType);
+
+ engine->RegisterScriptFunction("Reflections::Set^1", (void *)SetReflections);
+ engine->RegisterScriptFunction("Reflections::IsReflecting^0", (void *)IsReflectionsOn);
+ engine->RegisterScriptFunction("Reflections::SetCharacterReflected^2", (void *)SetCharacterReflected);
+ engine->RegisterScriptFunction("Reflections::GetCharacterReflected^1", (void *)GetCharacterReflected);
+ engine->RegisterScriptFunction("Reflections::SetObjectReflected^2", (void *)SetObjectReflected);
+ engine->RegisterScriptFunction("Reflections::GetObjectReflected^1", (void *)GetObjectReflected);
+ engine->RegisterScriptFunction("Reflections::ReplaceCharacterReflectionView^2", (void *)ReplaceCharacterReflectionView);
+ engine->RegisterScriptFunction("Reflections::SetObjectReflectionIgnoreScaling^2", (void *)SetObjectReflectionIgnoreScaling);
+ engine->RequestEventHook(AGSE_PRESCREENDRAW);
+ engine->RequestEventHook(AGSE_PREGUIDRAW);
+ engine->RequestEventHook(AGSE_POSTSCREENDRAW);
+ engine->RequestEventHook(AGSE_SAVEGAME);
+ engine->RequestEventHook(AGSE_RESTOREGAME);
+ engine->RequestEventHook(AGSE_ENTERROOM);
+ stars = new starstype [MAX_STARS];
+ Starfield.maxstars = MAX_STARS;
+ Starfield.depthmultiplier = 256;
+ Starfield.speed = 0.5;
+ Starfield.originx = 160;
+ Starfield.originy = 100;
+ Reflection.Characters = new charrefopt [engine->GetNumCharacters()]();
+ lens = new LensDistort [LENS_WIDTH * LENS_WIDTH]();
+ //PreMultiply_Alphas ();
+ plasmaroottype = 0;
+ Make_Sin_Lut();
+ Init_Raycaster();
+}
+
+void AGSPalRender::AGS_EngineShutdown() {
+ // no work to do here - but if we had created any dynamic sprites,
+ // we should delete them here
+ delete[] Reflection.Characters;
+ delete[] Reflection.Objects;
+ //QuitCleanup();
+}
+
+NumberPtr AGSPalRender::AGS_EngineOnEvent(int event, NumberPtr data) {
+ if (event == AGSE_PRESCREENDRAW && clutslot > 0) {
+ if (drawreflections) {
+ int32 sh, sw = 0;
+ engine->GetScreenDimensions(&sw, &sh, nullptr);
+ reflectionmap = new long[sw * sh]();
+ rcolormap = engine->CreateBlankBitmap(sw, sh, 8);
+ ralphamap = engine->CreateBlankBitmap(sw, sh, 8);
+ for (int i = 0; i < engine->GetNumCharacters(); i++) {
+ if (Reflection.Characters[i].reflect == 0) continue;
+ AGSCharacter *tempchar = engine->GetCharacter(i);
+ if (tempchar->room != engine->GetCurrentRoom()) continue; //if character isn't even in the room, go to next iteration.
+ int32 vx = tempchar->x;
+ int32 vy = tempchar->y;
+ engine->RoomToViewport(&vx, &vy);
+ AGSViewFrame *vf = engine->GetViewFrame(tempchar->view + 1, tempchar->loop, tempchar->frame);
+ int w = engine->GetSpriteWidth(vf->pic);
+ int h = engine->GetSpriteHeight(vf->pic);
+ vx = vx - (w / 2);
+ int32 vxmax = vx + w;
+ int32 vymax = vy + h;
+ if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
+ DrawReflections(i, 0);
+ }
+ for (int i = 0; i < engine->GetNumObjects(); i++) {
+ if (Reflection.Objects[i].reflect == 0) continue;
+ AGSObject *tempobj = engine->GetObject(i);
+ if (!tempobj->on) continue;
+ int32 vx = tempobj->x;
+ int32 vy = tempobj->baseline - tempobj->y;
+ engine->RoomToViewport(&vx, &vy);
+ int32 w = engine->GetSpriteWidth(tempobj->num);
+ int32 h = engine->GetSpriteHeight(tempobj->num);
+ int32 vxmax = vx + w;
+ int32 vymax = vy + h;
+ if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration
+ DrawReflections(i, 1);
+ }
+ BITMAP *virtsc = engine->GetVirtualScreen();
+ unsigned char **screenbuffer = engine->GetRawBitmapSurface(virtsc);
+ unsigned char **colorbuffer = engine->GetRawBitmapSurface(rcolormap);
+ unsigned char **alphabuffer = engine->GetRawBitmapSurface(ralphamap);
+ for (int y = 0; y < sh; y++)
+ for (int x = 0; x < sw; x++)
+ screenbuffer[y][x] = Mix::MixColorAlpha(colorbuffer[y][x], screenbuffer[y][x], alphabuffer[y][x]);
+ engine->ReleaseBitmapSurface(rcolormap);
+ engine->ReleaseBitmapSurface(ralphamap);
+ engine->ReleaseBitmapSurface(virtsc);
+ engine->FreeBitmap(rcolormap);
+ engine->FreeBitmap(ralphamap);
+ delete [] reflectionmap;
+ }
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 0) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 0) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_PREGUIDRAW && clutslot > 0) {
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 1) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 2) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_POSTSCREENDRAW && clutslot > 0) {
+ int i = 0;
+ if (LensOption.draw == 1 && LensOption.level == 3) DrawLens(LensOption.x, LensOption.y);
+ while (i < MAX_OVERLAYS) {
+ if (overlay[i].enabled && overlay[i].level == 2) {
+ DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype);
+ }
+ i++;
+ }
+ if (LensOption.draw == 1 && LensOption.level == 4) DrawLens(LensOption.x, LensOption.y);
+ }
+ if (event == AGSE_SAVEGAME) {
+ for (int i = 0; i < MAX_OVERLAYS; ++i) {
+ engine->FWrite(&overlay[i].sprite, sizeof(int), data);
+ engine->FWrite(&overlay[i].spritemask, sizeof(int), data);
+ engine->FWrite(&overlay[i].x, sizeof(int), data);
+ engine->FWrite(&overlay[i].y, sizeof(int), data);
+ engine->FWrite(&overlay[i].level, sizeof(int), data);
+ engine->FWrite(&overlay[i].trans, sizeof(int), data);
+ engine->FWrite(&overlay[i].blendtype, sizeof(int), data);
+ engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
+ }
+ engine->FWrite(&clutslot, sizeof(int), data);
+ engine->FWrite(&drawreflections, sizeof(int), data);
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data);
+ engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data);
+ engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ engine->FWrite(&sprite[j].x, sizeof(double), data);
+ engine->FWrite(&sprite[j].y, sizeof(double), data);
+ engine->FWrite(&sprite[j].texture, sizeof(int), data);
+ engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data);
+ engine->FWrite(&sprite[j].uDivW, sizeof(double), data);
+ engine->FWrite(&sprite[j].uDivH, sizeof(double), data);
+ engine->FWrite(&sprite[j].vMove, sizeof(double), data);
+ engine->FWrite(&sprite[j].hMove, sizeof(double), data);
+ engine->FWrite(&sprite[j].objectinteract, sizeof(char), data);
+ engine->FWrite(&sprite[j].view, sizeof(int), data);
+ engine->FWrite(&sprite[j].frame, sizeof(int), data);
+ engine->FWrite(&sprite[j].angle, sizeof(int), data);
+ }
+ for (int j = 0; j < 256; ++j) {
+ for (int k = 0; k < 4; ++k) {
+ engine->FWrite(&wallData[j].texture[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].solid[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].alpha[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data);
+ engine->FWrite(&wallData[j].mask[k], sizeof(int), data);
+ }
+ engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data);
+ }
+ engine->FWrite(&raycastOn, sizeof(bool), data);
+ engine->FWrite(&heightmapOn, sizeof(bool), data);
+ engine->FWrite(&posX, sizeof(double), data);
+ engine->FWrite(&posY, sizeof(double), data);
+ engine->FWrite(&dirX, sizeof(double), data);
+ engine->FWrite(&dirY, sizeof(double), data);
+ engine->FWrite(&planeX, sizeof(double), data);
+ engine->FWrite(&planeY, sizeof(double), data);
+ engine->FWrite(&moveSpeed, sizeof(double), data);
+ engine->FWrite(&rotSpeed, sizeof(double), data);
+ if (raycastOn) { //If the raycaster is active, we have additional data to save.
+ for (int i = 0; i < mapWidth; ++i)
+ for (int j = 0; j < mapHeight; ++j) {
+ engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data);
+ engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data);
+ engine->FWrite(&ceilingMap [i][j], sizeof(int), data);
+ engine->FWrite(&floorMap [i][j], sizeof(int), data);
+ engine->FWrite(&heightMap [i][j], sizeof(int), data);
+ }
+ }
+ engine->FWrite(&textureSlot, sizeof(int), data);
+ engine->FWrite(&skybox, sizeof(int), data);
+ engine->FWrite(&ambientlight, sizeof(int), data);
+ }
+ if (event == AGSE_RESTOREGAME) {
+
+
+ for (int i = 0; i < MAX_OVERLAYS; ++i) {
+ engine->FRead(&overlay[i].sprite, sizeof(int), data);
+ engine->FRead(&overlay[i].spritemask, sizeof(int), data);
+ engine->FRead(&overlay[i].x, sizeof(int), data);
+ engine->FRead(&overlay[i].y, sizeof(int), data);
+ engine->FRead(&overlay[i].level, sizeof(int), data);
+ engine->FRead(&overlay[i].trans, sizeof(int), data);
+ engine->FRead(&overlay[i].blendtype, sizeof(int), data);
+ engine->FRead(&overlay[i].enabled, sizeof(bool), data);
+ }
+ engine->FRead(&clutslot, sizeof(int), data);
+ engine->FRead(&drawreflections, sizeof(int), data);
+ for (int j = 0; j < 256; ++j) {
+ engine->FRead(&cycle_remap[j], sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Objective Palette, for palette mixing.
+ engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data);
+ engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data);
+ engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Raycaster Sprite struct, 256 instances.
+ engine->FRead(&sprite[j].x, sizeof(double), data);
+ engine->FRead(&sprite[j].y, sizeof(double), data);
+ engine->FRead(&sprite[j].texture, sizeof(int), data);
+ engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data);
+ engine->FRead(&sprite[j].uDivW, sizeof(double), data);
+ engine->FRead(&sprite[j].uDivH, sizeof(double), data);
+ engine->FRead(&sprite[j].vMove, sizeof(double), data);
+ engine->FRead(&sprite[j].hMove, sizeof(double), data);
+ engine->FRead(&sprite[j].objectinteract, sizeof(char), data);
+ engine->FRead(&sprite[j].view, sizeof(int), data);
+ engine->FRead(&sprite[j].frame, sizeof(int), data);
+ engine->FRead(&sprite[j].angle, sizeof(int), data);
+ }
+ for (int j = 0; j < 256; ++j) { //Save Raycaster wall type data.
+ for (int k = 0; k < 4; ++k) {
+ engine->FRead(&wallData[j].texture[k], sizeof(int), data);
+ engine->FRead(&wallData[j].solid[k], sizeof(int), data);
+ engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data);
+ engine->FRead(&wallData[j].alpha[k], sizeof(int), data);
+ engine->FRead(&wallData[j].blendtype[k], sizeof(int), data);
+ engine->FRead(&wallData[j].mask[k], sizeof(int), data);
+ }
+ engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data);
+ }
+ //Delete worldmap data if it exists.
+ engine->FRead(&raycastOn, sizeof(bool), data);
+ engine->FRead(&heightmapOn, sizeof(bool), data);
+ engine->FRead(&posX, sizeof(double), data);
+ engine->FRead(&posY, sizeof(double), data);
+ engine->FRead(&dirX, sizeof(double), data);
+ engine->FRead(&dirY, sizeof(double), data);
+ engine->FRead(&planeX, sizeof(double), data);
+ engine->FRead(&planeY, sizeof(double), data);
+ engine->FRead(&moveSpeed, sizeof(double), data);
+ engine->FRead(&rotSpeed, sizeof(double), data);
+ if (raycastOn) { //If the raycaster is currently running, we have additional data to load.
+ for (int i = 0; i < mapWidth; ++i) {
+ for (int j = 0; j < mapHeight; ++j) {
+ engine->FRead(&worldMap [i][j], sizeof(unsigned char), data);
+ engine->FRead(&lightMap [i][j], sizeof(unsigned char), data);
+ engine->FRead(&ceilingMap [i][j], sizeof(int), data);
+ engine->FRead(&floorMap [i][j], sizeof(int), data);
+ engine->FRead(&heightMap [i][j], sizeof(int), data);
+ seenMap [i][j] = 0;
+ }
+ }
+
+ //Reinitialize all the buffers and stuff.
+
+ }
+ engine->FRead(&textureSlot, sizeof(int), data);
+ if (textureSlot) MakeTextures(textureSlot);
+ engine->FRead(&skybox, sizeof(int), data);
+ engine->FRead(&ambientlight, sizeof(int), data);
+ LoadCLUT(clutslot);
+ }
+ if (event == AGSE_ENTERROOM) {
+ ResetRemapping();
+ delete[] Reflection.Objects;
+ Reflection.Objects = new objrefopt [engine->GetNumObjects()]();
+ }
+ return 0;
+}
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
diff --git a/engines/ags/plugins/ags_pal_render/pal_render.h b/engines/ags/plugins/ags_pal_render/pal_render.h
index 1ea7951138..1f160791cd 100644
--- a/engines/ags/plugins/ags_pal_render/pal_render.h
+++ b/engines/ags/plugins/ags_pal_render/pal_render.h
@@ -1,193 +1,193 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
-#define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
-
-#include "ags/lib/allegro.h"
-#include "ags/plugins/agsplugin.h"
-#include "common/algorithm.h"
-
-namespace AGS3 {
-namespace Plugins {
-namespace AGSPalRender {
-
-#define SCRIPT_FLOAT(x) int32 __script_float##x
-#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float))
-#define FLOAT_RETURN_TYPE int32
-#define RETURN_FLOAT(x) int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x
-
-struct PALSTRUCT {
- int r;
- int b;
- int g;
-};
-
-extern IAGSEngine *engine;
-extern unsigned char clut[65536];
-extern unsigned char cycle_remap [256];
-extern const int alphamultiply [4096];
-extern PALSTRUCT objectivepal[256];
-
-// this class exists solely to take advantage of g++'s
-// -fvisibility-inlines-hidden option, so that these
-// methods can be inlined without any trace or complaint
-class Mix {
-public:
-//unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha);
-//unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha);
- static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- //int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
- //int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
- //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
- int out_r, out_g, out_b;
- if (use_objpal == 0) {
- out_r = (objectivepal[rfg].r >> 1) *alpha + (palette[bg].r >> 1) *(255 - alpha);
- out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha);
- out_b = (objectivepal[rfg].b >> 1) *alpha + (palette[bg].b >> 1) *(255 - alpha);
- } else {
- out_r = (objectivepal[rfg].r >> 1) *alpha + (objectivepal[bg].r >> 1) *(255 - alpha);
- out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha);
- out_b = (objectivepal[rfg].b >> 1) *alpha + (objectivepal[bg].b >> 1) *(255 - alpha);
- }
- //char ralpha = MAX(0,MIN(63,alpha>>2));
- //unsigned char invralpha = 64-ralpha;
- //if (ralpha > alpha) engine->AbortGame ("wtf");
- //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)];
- //int out_g = alphamultiply[((palette[fg].g) <<6) +ralpha] + alphamultiply[((palette[bg].g) <<6) +(invralpha)];
- //int out_b = alphamultiply[((palette[fg].b>>1)<<6) +ralpha] + alphamultiply[((palette[bg].b>>1)<<6) +(invralpha)];
- out_r = (out_r + 1 + (out_r >> 8)) >> 8;
- out_g = (out_g + 1 + (out_g >> 8)) >> 8;
- out_b = (out_b + 1 + (out_b >> 8)) >> 8;
- //out_r = (out_r + 1 + (out_r >> 6)) >> 6;
- //out_g = (out_g + 1 + (out_g >> 6)) >> 6;
- //out_b = (out_b + 1 + (out_b >> 6)) >> 6;
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char(*clutp) = clut;
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- }
-
- static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) {
- unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- int i = 0;
- //int dark_r = (((palette[fg].r>>1) * (intensity))>>8);
- //int dark_b = (((palette[fg].b>>1) * (intensity))>>8);
- //int dark_g = (((palette[fg].g) * (intensity))>>8);
- int dark_r = (((objectivepal[rfg].r >> 1) * (intensity)) >> 8);
- int dark_b = (((objectivepal[rfg].b >> 1) * (intensity)) >> 8);
- int dark_g = (((objectivepal[rfg].g) * (intensity)) >> 8);
- i = ((dark_r << 11) | (dark_g << 5) | dark_b);
- unsigned char (*clutp) = clut;
- return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- }
-
- static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
- //unsigned char rbg = cycle_remap[bg]; //Saves on typing elsewhere.
- //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
- //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
- //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- int add_r, add_b, add_g = 0;
- //char ralpha = MAX(0,MIN(63,alpha>>2));
- //add_r = (((palette[fg].r>>1) * (alpha))>>8);
- //add_b = (((palette[fg].b>>1) * (alpha))>>8);
- //add_g = (((palette[fg].g) * (alpha))>>8);
- add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8);
- add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8);
- add_g = (((objectivepal[rfg].g) * (alpha)) >> 8);
- //int a_g = MAX(0,MIN(63,alpha>>2));
- //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6);
- //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6);
- //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6);
- //int out_r = MIN(31,(palette[bg].r>>1) + add_r);
- //int out_g = MIN(63, palette[bg].g + add_g);
- //int out_b = MIN(31,(palette[bg].b>>1) + add_b);
- int out_r, out_g, out_b;
- if (use_objpal == 0) {
- out_r = MIN(31, (palette[bg].r >> 1) + add_r);
- out_g = MIN(63, palette[bg].g + add_g);
- out_b = MIN(31, (palette[bg].b >> 1) + add_b);
- } else {
- out_r = MIN(31, (objectivepal [bg].r >> 1) + add_r);
- out_g = MIN(63, objectivepal [bg].g + add_g);
- out_b = MIN(31, (objectivepal [bg].b >> 1) + add_b);
- }
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
- }
-
- static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
- unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
- unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
- AGSColor *palette = engine->GetPalette();
- int i = 0;
- int mul_r, mul_b, mul_g = 0;
- int out_r, out_g, out_b = 0;
- if (use_objpal == 0) {
- mul_r = ((objectivepal[rfg].r >> 1) * (palette[rbg].r >> 1)) / 64;
- mul_b = ((objectivepal[rfg].b >> 1) * (palette[rbg].b >> 1)) / 64;
- mul_g = ((objectivepal[rfg].g * palette[rbg].g) / 64);
- out_r = ((palette[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
- out_g = (palette[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
- out_b = ((palette[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
- } else {
- mul_r = ((objectivepal[rfg].r >> 1) * (objectivepal[rbg].r >> 1)) / 64;
- mul_b = ((objectivepal[rfg].b >> 1) * (objectivepal[rbg].b >> 1)) / 64;
- mul_g = ((objectivepal[rfg].g * objectivepal[rbg].g) / 64);
-
- out_r = ((objectivepal[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
- out_g = (objectivepal[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
- out_b = ((objectivepal[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
- }
- i = ((out_r << 11) | (out_g << 5) | out_b);
- unsigned char (*clutp) = clut;
- unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
- //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
- //engine->ReleaseBitmapSurface (clutspr);
- return result;
- }
-
-};
-
-unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b);
-
-unsigned short root(unsigned short x);
-float FastSin(float x);
-float FastCos(float x);
-
-} // namespace AGSPalRender
-} // namespace Plugins
-} // namespace AGS3
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
+#define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H
+
+#include "ags/lib/allegro.h"
+#include "ags/plugins/agsplugin.h"
+#include "common/algorithm.h"
+
+namespace AGS3 {
+namespace Plugins {
+namespace AGSPalRender {
+
+#define SCRIPT_FLOAT(x) int32 __script_float##x
+#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float))
+#define FLOAT_RETURN_TYPE int32
+#define RETURN_FLOAT(x) int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x
+
+struct PALSTRUCT {
+ int r;
+ int b;
+ int g;
+};
+
+extern IAGSEngine *engine;
+extern unsigned char clut[65536];
+extern unsigned char cycle_remap [256];
+extern const int alphamultiply [4096];
+extern PALSTRUCT objectivepal[256];
+
+// this class exists solely to take advantage of g++'s
+// -fvisibility-inlines-hidden option, so that these
+// methods can be inlined without any trace or complaint
+class Mix {
+public:
+//unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha);
+//unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha);
+ static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ //int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha);
+ //int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha);
+ //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha);
+ int out_r, out_g, out_b;
+ if (use_objpal == 0) {
+ out_r = (objectivepal[rfg].r >> 1) *alpha + (palette[bg].r >> 1) *(255 - alpha);
+ out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha);
+ out_b = (objectivepal[rfg].b >> 1) *alpha + (palette[bg].b >> 1) *(255 - alpha);
+ } else {
+ out_r = (objectivepal[rfg].r >> 1) *alpha + (objectivepal[bg].r >> 1) *(255 - alpha);
+ out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha);
+ out_b = (objectivepal[rfg].b >> 1) *alpha + (objectivepal[bg].b >> 1) *(255 - alpha);
+ }
+ //char ralpha = MAX(0,MIN(63,alpha>>2));
+ //unsigned char invralpha = 64-ralpha;
+ //if (ralpha > alpha) engine->AbortGame ("wtf");
+ //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)];
+ //int out_g = alphamultiply[((palette[fg].g) <<6) +ralpha] + alphamultiply[((palette[bg].g) <<6) +(invralpha)];
+ //int out_b = alphamultiply[((palette[fg].b>>1)<<6) +ralpha] + alphamultiply[((palette[bg].b>>1)<<6) +(invralpha)];
+ out_r = (out_r + 1 + (out_r >> 8)) >> 8;
+ out_g = (out_g + 1 + (out_g >> 8)) >> 8;
+ out_b = (out_b + 1 + (out_b >> 8)) >> 8;
+ //out_r = (out_r + 1 + (out_r >> 6)) >> 6;
+ //out_g = (out_g + 1 + (out_g >> 6)) >> 6;
+ //out_b = (out_b + 1 + (out_b >> 6)) >> 6;
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char *clutp = clut;
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ }
+
+ static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) {
+ unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ int i = 0;
+ //int dark_r = (((palette[fg].r>>1) * (intensity))>>8);
+ //int dark_b = (((palette[fg].b>>1) * (intensity))>>8);
+ //int dark_g = (((palette[fg].g) * (intensity))>>8);
+ int dark_r = (((objectivepal[rfg].r >> 1) * (intensity)) >> 8);
+ int dark_b = (((objectivepal[rfg].b >> 1) * (intensity)) >> 8);
+ int dark_g = (((objectivepal[rfg].g) * (intensity)) >> 8);
+ i = ((dark_r << 11) | (dark_g << 5) | dark_b);
+ unsigned char *clutp = clut;
+ return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ }
+
+ static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots.
+ //unsigned char rbg = cycle_remap[bg]; //Saves on typing elsewhere.
+ //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot);
+ //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory.");
+ //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr);
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ int add_r, add_b, add_g = 0;
+ //char ralpha = MAX(0,MIN(63,alpha>>2));
+ //add_r = (((palette[fg].r>>1) * (alpha))>>8);
+ //add_b = (((palette[fg].b>>1) * (alpha))>>8);
+ //add_g = (((palette[fg].g) * (alpha))>>8);
+ add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8);
+ add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8);
+ add_g = (((objectivepal[rfg].g) * (alpha)) >> 8);
+ //int a_g = MAX(0,MIN(63,alpha>>2));
+ //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6);
+ //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6);
+ //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6);
+ //int out_r = MIN(31,(palette[bg].r>>1) + add_r);
+ //int out_g = MIN(63, palette[bg].g + add_g);
+ //int out_b = MIN(31,(palette[bg].b>>1) + add_b);
+ int out_r, out_g, out_b;
+ if (use_objpal == 0) {
+ out_r = MIN(31, (palette[bg].r >> 1) + add_r);
+ out_g = MIN(63, palette[bg].g + add_g);
+ out_b = MIN(31, (palette[bg].b >> 1) + add_b);
+ } else {
+ out_r = MIN(31, (objectivepal [bg].r >> 1) + add_r);
+ out_g = MIN(63, objectivepal [bg].g + add_g);
+ out_b = MIN(31, (objectivepal [bg].b >> 1) + add_b);
+ }
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char *clutp = clut;
+ unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+ }
+
+ static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) {
+ unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots.
+ unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere.
+ AGSColor *palette = engine->GetPalette();
+ int i = 0;
+ int mul_r, mul_b, mul_g = 0;
+ int out_r, out_g, out_b = 0;
+ if (use_objpal == 0) {
+ mul_r = ((objectivepal[rfg].r >> 1) * (palette[rbg].r >> 1)) / 64;
+ mul_b = ((objectivepal[rfg].b >> 1) * (palette[rbg].b >> 1)) / 64;
+ mul_g = ((objectivepal[rfg].g * palette[rbg].g) / 64);
+ out_r = ((palette[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
+ out_g = (palette[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
+ out_b = ((palette[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
+ } else {
+ mul_r = ((objectivepal[rfg].r >> 1) * (objectivepal[rbg].r >> 1)) / 64;
+ mul_b = ((objectivepal[rfg].b >> 1) * (objectivepal[rbg].b >> 1)) / 64;
+ mul_g = ((objectivepal[rfg].g * objectivepal[rbg].g) / 64);
+
+ out_r = ((objectivepal[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63;
+ out_g = (objectivepal[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63;
+ out_b = ((objectivepal[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63;
+ }
+ i = ((out_r << 11) | (out_g << 5) | out_b);
+ unsigned char *clutp = clut;
+ unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one.
+ //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one.
+ //engine->ReleaseBitmapSurface (clutspr);
+ return result;
+ }
+
+};
+
+unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b);
+
+unsigned short root(unsigned short x);
+float FastSin(float x);
+float FastCos(float x);
+
+} // namespace AGSPalRender
+} // namespace Plugins
+} // namespace AGS3
+
+#endif
More information about the Scummvm-git-logs
mailing list