water.c
来自「linux下的任天堂模拟器代码。供大家参考。」· C语言 代码 · 共 249 行
C
249 行
/*Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )http://www.zsnes.comhttp://sourceforge.net/projects/zsneshttps://zsnes.bountysource.comThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseversion 2 as published by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//* Water effects implementation by Pharos, Nach, et al. */#ifdef __UNIXSDL__#include "../gblhdr.h"#else#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <math.h>#include <memory.h>#include <string.h>#endif#include "fixsin.h"extern char *vidbuffer;#define SCRW 288#define SCRH 224static unsigned char vscr[SCRW*SCRH];static int Height[2][SCRW*SCRH];extern char NetPlayNoMore;static void DrawWaterWithLight(int *ptr,int light);static void SineBlob(int x, int y, int radius, int height, int page);static void CalcWater(int *nptr,int *optr,int density);static int ox=80,oy=60;static int xang,yang;static int density=5;static int Hpage=0;static int mode=0x0001;static int offset;static int pheight=400;static int radius=30;extern char GUIEffect;void DrawWater(void){ DrawWaterWithLight(Height[Hpage],1); if (GUIEffect==2) { mode=0x0001; } else { mode = 0x0004; } if(mode&2) { int x,y; x=rand()%(SCRW-2)+1; y=rand()%(SCRH-2)+1; Height[Hpage][y*SCRW+x]=rand()%(pheight<<2); } /* the surfer */ if(mode&1) { int x,y; x = (SCRW/2) + ((((FSin( (xang* 65) >>8) >>8) * (FSin( (xang*349) >>8) >>8)) * ((SCRW-8)/2)) >> 16); y = (SCRH/2) + ((((FSin( (yang*377) >>8) >>8) *(FSin( (yang* 84) >>8) >>8)) * ((SCRH-8)/2)) >> 16); xang += 13; yang += 12; if(mode & 0x4000) { offset = (oy+y)/2*SCRW + (ox+x)/2; Height[Hpage][offset] = pheight; Height[Hpage][offset + 1] = Height[Hpage][offset - 1] = Height[Hpage][offset + SCRW] = Height[Hpage][offset - SCRW] = pheight >> 1; offset = y*SCRW + x; Height[Hpage][offset] = pheight<<1; Height[Hpage][offset + 1] = Height[Hpage][offset - 1] = Height[Hpage][offset + SCRW] = Height[Hpage][offset - SCRW] = pheight; } else { SineBlob((ox+x)/2, (oy+y)/2, 3, -1200, Hpage); SineBlob(x, y, 4, -2000, Hpage); } ox = x; oy = y; } if(mode&4) { int x,y; if(rand()%14 == 7) { x=rand()%(SCRW-2)+1; y=rand()%(SCRH-2)+1; SineBlob(x, y, radius, -pheight*6, Hpage); } } CalcWater(Height[Hpage^1], Height[Hpage], density); Hpage ^= 1; /* flip flop */}void DrawWaterWithLight(int *ptr,int light){ int dx,dy; int x,y; int c; int p; int offset = SCRW+1; if(ptr == NULL) { return; } for(y=((SCRH-1)*SCRW); offset < y; offset+=2) { for(x = offset+SCRW-2;offset<x;offset++) { dx=ptr[offset]-ptr[offset+1]; dy=ptr[offset]-ptr[offset+SCRW]; p=offset+SCRW*(dy>>3)+(dx>>3); if (p>(SCRH*SCRW)) p = (p % SCRW) + ((SCRH-((p - (SCRH*SCRW)) / SCRW)) * SCRW); if (p<0) p = (SCRW + (p % SCRW)) + abs(p / SCRW) * SCRW; c=vidbuffer[p]; c-=(dx>>light); (c<1) ? c=1 : (c > 31) ? c=31 : 0; vscr[offset]=c; offset++; dx=ptr[offset]-ptr[offset+1]; dy=ptr[offset]-ptr[offset+SCRW]; p=offset+SCRW*(dy>>3)+(dx>>3); if (p>(SCRH*SCRW)) p = (p % SCRW) + ((SCRH-((p - (SCRH*SCRW)) / SCRW)) * SCRW); if (p<0) p = (SCRW + (p % SCRW)) + abs(p / SCRW) * SCRW; c=vidbuffer[p]; c-=(dx>>light); (c<1) ? c=1 : (c > 31) ? c=31 : 0; vscr[offset]=c; } } memcpy( vidbuffer,vscr,SCRW*SCRH);}void CalcWater(int *nptr,int *optr,int density){ int newh; int count = SCRW+1; int x,y; for(y = (SCRH-1) * SCRW;count<y;count+=2) { for(x = count+SCRW-2;count<x;count++) { newh = ((optr[count+SCRW] +optr[count-SCRW] +optr[count+1] +optr[count-1] +optr[count-SCRW-1] +optr[count-SCRW+1] +optr[count+SCRW-1] +optr[count+SCRW+1] ) >> 2) - nptr[count]; nptr[count] = newh - (newh >> density); } }}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.0f/(float)radius)*(1024.0f/(float)radius); if(x<0) x = 1+radius+ rand()%(SCRW-2*radius-1); if(y<0) y = 1+radius+ rand()%(SCRH-2*radius-1); radsquare = (radius*radius); height /= 8; 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 > SCRW-1) right -= (x+radius-SCRW+1); if(y + radius > SCRH-1) bottom-= (y+radius-SCRH+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][SCRW*(cy+y) + cx+x] += (int)((FCos(dist)+0xffff)*(height)) >> 19; } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?