summaryrefslogtreecommitdiffstats
path: root/mufhd0/water.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mufhd0/water.cpp')
-rw-r--r--mufhd0/water.cpp615
1 files changed, 0 insertions, 615 deletions
diff --git a/mufhd0/water.cpp b/mufhd0/water.cpp
deleted file mode 100644
index 763bd27..0000000
--- a/mufhd0/water.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- Water lib 0.1
- (C)2000 Denis Roio - aka jaromil
-
- Thanks go to Federico 'pix' Feroldi for the original
- water algorithm idea...
- Some optimizations added by Jason Hood.
- Some other optimizations by Scott Scriven.
- Further optimizations followed...
-*/
-
-#include <iostream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <SDL/SDL.h>
-#include "datatype.h"
-#include "fixsin.h"
-
-using namespace std;
-
-#define MAXWATERWIDTH 768
-#define MAXWATERHEIGHT 768
-
-/* water physics */
-#define WATER 1
-#define JELLY 2
-#define SLUDGE 3
-#define SUPER_SLUDGE 4
-
-/* The Height field... Two pages, so that the filter will work correctly */
-int Height[2][MAXWATERHEIGHT * MAXWATERHEIGHT];
-
-/* Yes, I've got three copies of the background, all next to each other.
- Press 's' a bunch of times to see why...
- */
-
-static byte BkGdImagePre[MAXWATERWIDTH * MAXWATERHEIGHT];
-static byte BkGdImage[MAXWATERWIDTH * MAXWATERHEIGHT];
-static byte BkGdImagePost[MAXWATERWIDTH * MAXWATERHEIGHT];
-
-byte *bufptr;
-int waterwidth;
-int waterheight;
-
-// water effect variables
-int Hpage = 0;
-int xang, yang;
-int swirlangle;
-int x, y, ox = 80, oy = 60;
-int done = 0;
-int mode=0x4000;
-
-/* density: water density (step 1)
- pheight: splash height (step 40)
- radius: waterdrop radius (step 1)
- light: light level (step 1)
-*/
-int density = 4, pheight = 600, radius = 30;
-int movement=1;
-int light=0;
-int offset;
-
-int water_surfacesize;
-int calc_optimization;
-
-/* *** clear:
- memset(Height[0], 0, sizeof(int)*waterwidth*waterheight);
- memset(Height[1], 0, sizeof(int)*waterwidth*waterheight);
- *** distort /exaggerate water:
- memset(Height[Hpage], 0, sizeof(int)*waterwidth*waterheight);
- *** water physics
- mode |= 0x40000;
- density=4; light=1; pheight=600;
- *** jelly physics
- mode &= 0xBFFF;
- density=3; pheight=400;
- *** sludge physics
- mode &= 0xBFFF;
- density=8; pheight=400;
- *** super sludge physics
- mode &= 0xBFFF;
- density=8; pheight=400;
-*/
-
-void DrawWaterNoLight(int page);
-void DrawWaterWithLight(int page, int LightModifier);
-void CalcWater(int npage, int density);
-void SmoothWater(int npage);
-
-void HeightBlob(int x, int y, int radius, int height, int page);
-void HeightBox (int x, int y, int radius, int height, int page);
-
-void WarpBlob(int x, int y, int radius, int height, int page);
-void SineBlob(int x, int y, int radius, int height, int page);
-
-SDL_Surface *water_init(char *imagefile, SDL_Surface *screen) {
- SDL_Palette *palette;
- SDL_Surface *image;
-
- randomize();
- image = SDL_LoadBMP(imagefile);
- if (image == NULL) {
- cout << "! Error loading water imagefile\n";
- cout << "!!! Sorry, exiting.\n";
- exit(1);
- }
-
- palette = image->format->palette;
-
- if ((image->format->BitsPerPixel != 8) || (palette == NULL))
- {
- cout << "! Water imagefile must have 8bit depth and have a palette\n";
- cout << "!!! Sorry, exiting.\n";
- exit(1);
- }
-
- if ((image->format->BitsPerPixel != 8) || (image->format->palette == NULL))
- {
- cout << "! Screen for water effect must have 8 bit depth and have a palette\n";
- cout << "!!! Sorry, exiting.\n";
- exit(1);
- }
-
- waterwidth = image->w;
- waterheight = image->h;
-
- FCreateSines();
-
- // misc optimization variables
- water_surfacesize = sizeof(int)*waterwidth*waterheight;
- calc_optimization = (waterheight-1)*waterwidth;
-
- /* Fill the extra palette entries with white and set the display palette */
- {
- int nwhite;
-
- nwhite = 256-palette->ncolors;
- memset(&palette->colors[palette->ncolors], 255, nwhite*sizeof(SDL_Color));
- SDL_SetColors(screen, palette->colors, 0, 256);
- }
-
- xang = rand()%2048;
- yang = rand()%2048;
- swirlangle = rand()%2048;
-
- memset(Height[0], 0, water_surfacesize);
- memset(Height[1], 0, water_surfacesize);
-
- bufptr = (unsigned char*)image->pixels;
- memcpy(BkGdImagePre, bufptr, waterwidth*waterheight);
- memcpy(BkGdImage, bufptr, waterwidth*waterheight);
- memcpy(BkGdImagePost, bufptr, waterwidth*waterheight);
-
- return(image);
-}
-
-void water_clear() {
- memset(Height[0], 0, water_surfacesize);
- memset(Height[1], 0, water_surfacesize);
-}
-
-void water_distort() {
- if(movement)
- memset(Height[Hpage], 0, water_surfacesize);
- else
- SmoothWater(Hpage);
-}
-
-void water_setphysics(int physics) {
- switch(physics) {
- case WATER:
- mode |= 0x4000;
- density=4;
- light=1;
- pheight=600;
- break;
- case JELLY:
- mode &= 0xBFFF;
- density=3;
- pheight=400;
- break;
- case SLUDGE:
- mode &= 0xBFFF;
- density=6;
- pheight=400;
- break;
- case SUPER_SLUDGE:
- mode &=0xBFFF;
- density=8;
- pheight=400;
- break;
- }
-}
-
-void water_update() {
- if(light)
- DrawWaterWithLight(Hpage, light-1);
- else
- DrawWaterNoLight(Hpage);
-
- CalcWater(Hpage^1, density);
- Hpage ^=1 ;
-}
-
-void water_drop(int x, int y) {
- Height[Hpage][y*waterwidth + x] = rand()%(pheight<<2);
-}
-
-void water_bigsplash(int x, int y) {
- if(mode & 0x4000)
- HeightBlob(x, y, (radius>>1), pheight, Hpage);
- else
- SineBlob(x, y, radius, -pheight*6, Hpage);
-}
-
-void water_surfer() {
- x = (waterwidth>>1)
- + ((
- (
- (FSin( (xang* 65) >>8) >>8) *
- (FSin( (xang*349) >>8) >>8)
- ) * ((waterwidth-8)>>1)
- ) >> 16);
- y = (waterheight>>1)
- + ((
- (
- (FSin( (yang*377) >>8) >>8) *
- (FSin( (yang* 84) >>8) >>8)
- ) * ((waterheight-8)>>1)
- ) >> 16);
- xang += 13;
- yang += 12;
-
- if(mode & 0x4000)
- {
- offset = (oy+y)/2*waterwidth + ((ox+x)>>1);
- Height[Hpage][offset] = pheight;
- Height[Hpage][offset + 1] =
- Height[Hpage][offset - 1] =
- Height[Hpage][offset + waterwidth] =
- Height[Hpage][offset - waterwidth] = pheight >> 1;
-
- offset = y*waterwidth + x;
- Height[Hpage][offset] = pheight<<1;
- Height[Hpage][offset + 1] =
- Height[Hpage][offset - 1] =
- Height[Hpage][offset + waterwidth] =
- Height[Hpage][offset - waterwidth] = pheight;
- }
- else
- {
- SineBlob(((ox+x)>>1), ((oy+y)>>1), 3, -1200, Hpage);
- SineBlob(x, y, 4, -2000, Hpage);
- }
-
- ox = x;
- oy = y;
-}
-
-void water_swirl() {
- x = (waterwidth>>1)
- + ((
- (FCos(swirlangle)) * (25)
- ) >> 16);
- y = (waterheight>>1)
- + ((
- (FSin(swirlangle)) * (25)
- ) >> 16);
- swirlangle += 50;
- if(mode & 0x4000)
- HeightBlob(x,y, radius>>2, pheight, Hpage);
- else
- WarpBlob(x, y, radius, pheight, Hpage);
-}
-
-void DrawWaterNoLight(int page)
-{
-
- int dx, dy;
- int x, y;
- int c;
-
- int offset=waterwidth + 1;
-
- int *ptr = &Height[page][0];
-
- for (y = calc_optimization; offset < y; offset += 2)
- {
- for (x = offset+waterwidth-2; offset < x; offset++)
- {
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+waterwidth];
- c = BkGdImage[offset + waterwidth*(dy>>3) + (dx>>3)];
-
- /* If anyone knows a better/faster way to do this, please tell me... */
- bufptr[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
-
- offset++;
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+waterwidth];
- c = BkGdImage[offset + waterwidth*(dy>>3) + (dx>>3)];
- bufptr[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
-
- }
- }
-}
-
-void DrawWaterWithLight(int page, int LightModifier)
-{
-
- int dx, dy;
- int x, y;
- int c;
-
- int offset=waterwidth + 1;
-
- int *ptr = &Height[page][0];
-
-
- for (y = calc_optimization; offset < y; offset += 2)
- {
- for (x = offset+waterwidth-2; offset < x; offset++)
- {
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+waterwidth];
-
- c = BkGdImage[offset + waterwidth*(dy>>3) + (dx>>3)] - (dx>>LightModifier);
-
- /* If anyone knows a better/faster way to do this, please tell me... */
- bufptr[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
-
- offset++;
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+waterwidth];
- c = BkGdImage[offset + waterwidth*(dy>>3) + (dx>>3)] - (dx>>LightModifier);
- bufptr[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
-
- }
- }
-}
-
-void CalcWater(int npage, int density)
-{
- int newh;
- int count = waterwidth + 1;
-
- int *newptr = &Height[npage][0];
- int *oldptr = &Height[npage^1][0];
-
- int x, y;
-
- /* Sorry, this function might not be as readable as I'd like, because
- I optimized it somewhat. (enough to make me feel satisfied with it)
- */
- for (y = calc_optimization; count < y; count += 2)
- {
- for (x = count+waterwidth-2; count < x; count++)
- {
-/* This does the eight-pixel method. It looks much better. */
-
- newh = ((oldptr[count + waterwidth]
- + oldptr[count - waterwidth]
- + oldptr[count + 1]
- + oldptr[count - 1]
- + oldptr[count - waterwidth - 1]
- + oldptr[count - waterwidth + 1]
- + oldptr[count + waterwidth - 1]
- + oldptr[count + waterwidth + 1]
- ) >> 2 )
- - newptr[count];
-
-
- newptr[count] = newh - (newh >> density);
- }
- }
-}
-
-void SmoothWater(int npage)
-{
- int newh;
- int count = waterwidth + 1;
-
- int *newptr = &Height[npage][0];
- int *oldptr = &Height[npage^1][0];
-
- int x, y;
-
- /* Sorry, this function might not be as readable as I'd like, because
- I optimized it somewhat. (enough to make me feel satisfied with it)
- */
-
- for(y=1; y<waterheight-1; y++)
- {
- for(x=1; x<waterwidth-1; x++)
- {
-/* This does the eight-pixel method. It looks much better. */
-
- newh = ((oldptr[count + waterwidth]
- + oldptr[count - waterwidth]
- + oldptr[count + 1]
- + oldptr[count - 1]
- + oldptr[count - waterwidth - 1]
- + oldptr[count - waterwidth + 1]
- + oldptr[count + waterwidth - 1]
- + oldptr[count + waterwidth + 1]
- ) >> 3 )
- + newptr[count];
-
-
- newptr[count] = newh>>1;
- count++;
- }
- count += 2;
- }
-}
-
-void CalcWaterBigFilter(int npage, int density)
-{
- int newh;
- int count = (waterwidth<<1) + 2;
-
- int *newptr = &Height[npage][0];
- int *oldptr = &Height[npage^1][0];
-
- int x, y;
-
- /* Sorry, this function might not be as readable as I'd like, because
- I optimized it somewhat. (enough to make me feel satisfied with it)
- */
-
- for(y=2; y<waterheight-2; y++)
- {
- for(x=2; x<waterwidth-2; x++)
- {
-/* This does the 25-pixel method. It looks much okay. */
-
- newh = (
- (
- (
- (oldptr[count + waterwidth]
- + oldptr[count - waterwidth]
- + oldptr[count + 1]
- + oldptr[count - 1]
- )<<1)
- + ((oldptr[count - waterwidth - 1]
- + oldptr[count - waterwidth + 1]
- + oldptr[count + waterwidth - 1]
- + oldptr[count + waterwidth + 1]))
- + ( (
- oldptr[count - (waterwidth<<1)]
- + oldptr[count + (waterwidth<<1)]
- + oldptr[count - 2]
- + oldptr[count + 2]
- ) >> 1 )
- + ( (
- oldptr[count - (waterwidth<<1) - 1]
- + oldptr[count - (waterwidth<<1) + 1]
- + oldptr[count + (waterwidth<<1) - 1]
- + oldptr[count + (waterwidth<<1) + 1]
- + oldptr[count - 2 - waterwidth]
- + oldptr[count - 2 + waterwidth]
- + oldptr[count + 2 - waterwidth]
- + oldptr[count + 2 + waterwidth]
- ) >> 2 )
- )
- >> 3)
- - (newptr[count]);
-
-
- newptr[count] = newh - (newh >> density);
- count++;
- }
- count += 4;
- }
-}
-
-void HeightBlob(int x, int y, int radius, int height, int page)
-{
- int rquad;
- int cx, cy, cyq;
- int left, top, right, bottom;
-
-
- rquad = radius * radius;
-
- /* Make a randomly-placed blob... */
- if(x<0) x = 1+radius+ rand()%(waterwidth-2*radius-1);
- if(y<0) y = 1+radius+ rand()%(waterheight-2*radius-1);
-
- left=-radius; right = radius;
- top=-radius; bottom = radius;
-
- /* Perform edge clipping... */
- if(x - radius < 1) left -= (x-radius-1);
- if(y - radius < 1) top -= (y-radius-1);
- if(x + radius > waterwidth-1) right -= (x+radius-waterwidth+1);
- if(y + radius > waterheight-1) bottom-= (y+radius-waterheight+1);
-
-
- for(cy = top; cy < bottom; cy++)
- {
- cyq = cy*cy;
- for(cx = left; cx < right; cx++)
- {
- if(cx*cx + cyq < rquad)
- Height[page][waterwidth*(cy+y) + (cx+x)] += height;
- }
- }
-}
-
-
-void HeightBox (int x, int y, int radius, int height, int page)
-{
- int cx, cy;
- int left, top, right, bottom;
-
-
- if(x<0) x = 1+radius+ rand()%(waterwidth-2*radius-1);
- if(y<0) y = 1+radius+ rand()%(waterheight-2*radius-1);
-
- left=-radius; right = radius;
- top=-radius; bottom = radius;
-
- /* Perform edge clipping... */
- if(x - radius < 1) left -= (x-radius-1);
- if(y - radius < 1) top -= (y-radius-1);
- if(x + radius > waterwidth-1) right -= (x+radius-waterwidth+1);
- if(y + radius > waterheight-1) bottom-= (y+radius-waterheight+1);
-
- for(cy = top; cy < bottom; cy++)
- {
- for(cx = left; cx < right; cx++)
- {
- Height[page][waterwidth*(cy+y) + (cx+x)] = height;
- }
- }
-
-}
-
-void WarpBlob(int x, int y, int radius, int height, int page)
-{
- int cx, cy;
- int left,top,right,bottom;
- int square;
- int radsquare = radius * radius;
-
- radsquare = (radius*radius);
-
- height = height>>5;
-
- left=-radius; right = radius;
- top=-radius; bottom = radius;
-
- /* Perform edge clipping... */
- if(x - radius < 1) left -= (x-radius-1);
- if(y - radius < 1) top -= (y-radius-1);
- if(x + radius > waterwidth-1) right -= (x+radius-waterwidth+1);
- if(y + radius > waterheight-1) bottom-= (y+radius-waterheight+1);
-
- for(cy = top; cy < bottom; cy++)
- {
- for(cx = left; cx < right; cx++)
- {
- square = cy*cy + cx*cx;
- if(square < radsquare)
- {
- Height[page][waterwidth*(cy+y) + cx+x]
- += (int)((radius-sqrt(square))*(float)(height));
- }
- }
- }
-}
-
-void SineBlob(int x, int y, int radius, int height, int page)
-{
- int cx, cy;
- int left,top,right,bottom;
- int square, dist;
- int radsquare = radius * radius;
- float length = (1024.0/(float)radius)*(1024.0/(float)radius);
-
- if(x<0) x = 1+radius+ rand()%(waterwidth-2*radius-1);
- if(y<0) y = 1+radius+ rand()%(waterheight-2*radius-1);
-
-
- radsquare = (radius*radius);
-
-
- left=-radius; right = radius;
- top=-radius; bottom = radius;
-
-
- /* Perform edge clipping... */
- if(x - radius < 1) left -= (x-radius-1);
- if(y - radius < 1) top -= (y-radius-1);
- if(x + radius > waterwidth-1) right -= (x+radius-waterwidth+1);
- if(y + radius > waterheight-1) bottom-= (y+radius-waterheight+1);
-
- for(cy = top; cy < bottom; cy++)
- {
- for(cx = left; cx < right; cx++)
- {
- square = cy*cy + cx*cx;
- if(square < radsquare)
- {
- dist = (int)(sqrt(square*length));
- Height[page][waterwidth*(cy+y) + cx+x]
- += (int)((FCos(dist)+0xffff)*(height)) >> 19;
- }
- }
- }
-}
-