/**
* Powder Toy - graphics
*
* 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 3 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, see .
*/
#include
#include
#include
#ifdef WIN32
#include
#endif
#if defined(OGLR)
#ifdef MACOSX
#include
#include
#elif defined(WIN32)
#include
#include
#include
#else
#include
#include
#endif
#endif
#include
#include
#include "gravity.h"
#include
#define INCLUDE_SHADERS
#include
#include
#define INCLUDE_FONTDATA
#include
#include
#include "hmap.h"
#ifdef LUACONSOLE
#include
#endif
#if defined(LIN32) || defined(LIN64)
#include "icon.h"
#endif
#ifdef WIN32
IMAGE_DOS_HEADER __ImageBase;
#endif
//unsigned cmode = CM_FIRE;
unsigned int *render_modes;
unsigned int render_mode;
unsigned int colour_mode;
unsigned int *display_modes;
unsigned int display_mode;
SDL_Surface *sdl_scrn;
int sdl_scale = 1;
#ifdef OGLR
GLuint zoomTex, vidBuf, airBuf, fireAlpha, glowAlpha, blurAlpha, partsFboTex, partsFbo, partsTFX, partsTFY, airPV, airVY, airVX;
GLuint fireProg, airProg_Pressure, airProg_Velocity, airProg_Cracker, lensProg;
#endif
int emp_decor = 0;
int sandcolour_r = 0;
int sandcolour_g = 0;
int sandcolour_b = 0;
int sandcolour_frame = 0;
unsigned char fire_r[YRES/CELL][XRES/CELL];
unsigned char fire_g[YRES/CELL][XRES/CELL];
unsigned char fire_b[YRES/CELL][XRES/CELL];
unsigned int fire_alpha[CELL*3][CELL*3];
pixel *pers_bg;
char * flm_data;
int flm_data_points = 4;
pixel flm_data_colours[] = {PIXPACK(0xAF9F0F), PIXPACK(0xDFBF6F), PIXPACK(0x60300F), PIXPACK(0x000000)};
float flm_data_pos[] = {1.0f, 0.9f, 0.5f, 0.0f};
char * plasma_data;
int plasma_data_points = 5;
pixel plasma_data_colours[] = {PIXPACK(0xAFFFFF), PIXPACK(0xAFFFFF), PIXPACK(0x301060), PIXPACK(0x301040), PIXPACK(0x000000)};
float plasma_data_pos[] = {1.0f, 0.9f, 0.5f, 0.25, 0.0f};
void init_display_modes()
{
int i;
display_modes = calloc(1, sizeof(unsigned int));
render_modes = calloc(2, sizeof(unsigned int));
display_modes[0] = 0;
render_modes[0] = RENDER_FIRE;
render_modes[1] = 0;
update_display_modes();
}
// Combine all elements of the display_modes and render_modes arrays into single variables using bitwise or
void update_display_modes()
{
int i;
display_mode = 0;
i = 0;
while(display_modes[i])
{
display_mode |= display_modes[i];
i++;
}
render_mode = 0;
i = 0;
while(render_modes[i])
{
render_mode |= render_modes[i];
i++;
}
}
char * generate_gradient(pixel * colours, float * points, int pointcount, int size)
{
int cp, i, j;
pixel ptemp;
char * newdata = malloc(size * 3);
float poss, pose, temp;
memset(newdata, 0, size*3);
//Sort the Colours and Points
for (i = (pointcount - 1); i > 0; i--)
{
for (j = 1; j <= i; j++)
{
if (points[j-1] > points[j])
{
temp = points[j-1];
points[j-1] = points[j];
points[j] = temp;
ptemp = colours[j-1];
colours[j-1] = colours[j];
colours[j] = ptemp;
}
}
}
i = 0;
j = 1;
poss = points[i];
pose = points[j];
for (cp = 0; cp < size; cp++)
{
float cpos = (float)cp / (float)size, ccpos, cccpos;
if(cpos > pose && j+1 < pointcount)
{
poss = points[++i];
pose = points[++j];
}
ccpos = cpos - poss;
cccpos = ccpos / (pose - poss);
if(cccpos > 1.0f)
cccpos = 1.0f;
newdata[(cp*3)] = PIXR(colours[i])*(1.0f-cccpos) + PIXR(colours[j])*(cccpos);
newdata[(cp*3)+1] = PIXG(colours[i])*(1.0f-cccpos) + PIXG(colours[j])*(cccpos);
newdata[(cp*3)+2] = PIXB(colours[i])*(1.0f-cccpos) + PIXB(colours[j])*(cccpos);
}
return newdata;
}
void *ptif_pack(pixel *src, int w, int h, int *result_size){
int i = 0, datalen = (w*h)*3, cx = 0, cy = 0;
unsigned char *red_chan = calloc(1, w*h);
unsigned char *green_chan = calloc(1, w*h);
unsigned char *blue_chan = calloc(1, w*h);
unsigned char *data = malloc(((w*h)*3)+8);
unsigned char *result = malloc(((w*h)*3)+8);
for(cx = 0; cx>8;
result[6] = h;
result[7] = h>>8;
i -= 8;
if(BZ2_bzBuffToBuffCompress((char *)(result+8), (unsigned *)&i, (char *)data, datalen, 9, 0, 0) != BZ_OK){
free(data);
free(result);
return NULL;
}
*result_size = i+8;
free(data);
return result;
}
pixel *ptif_unpack(void *datain, int size, int *w, int *h){
int width, height, i, cx, cy, resCode;
unsigned char *red_chan;
unsigned char *green_chan;
unsigned char *blue_chan;
unsigned char *data = datain;
unsigned char *undata;
pixel *result;
if(size<16){
printf("Image empty\n");
return NULL;
}
if(!(data[0]=='P' && data[1]=='T' && data[2]=='i')){
printf("Image header invalid\n");
return NULL;
}
width = data[4]|(data[5]<<8);
height = data[6]|(data[7]<<8);
i = (width*height)*3;
undata = calloc(1, (width*height)*3);
red_chan = calloc(1, width*height);
green_chan = calloc(1, width*height);
blue_chan = calloc(1, width*height);
result = calloc(width*height, PIXELSIZE);
resCode = BZ2_bzBuffToBuffDecompress((char *)undata, (unsigned *)&i, (char *)(data+8), size-8, 0, 0);
if (resCode){
printf("Decompression failure, %d\n", resCode);
free(red_chan);
free(green_chan);
free(blue_chan);
free(undata);
free(result);
return NULL;
}
if(i != (width*height)*3){
printf("Result buffer size mismatch, %d != %d\n", i, (width*height)*3);
free(red_chan);
free(green_chan);
free(blue_chan);
free(undata);
free(result);
return NULL;
}
memcpy(red_chan, undata, width*height);
memcpy(green_chan, undata+(width*height), width*height);
memcpy(blue_chan, undata+((width*height)*2), width*height);
for(cx = 0; cx sw && rh > sh){
float fx, fy, fyc, fxc;
double intp;
pixel tr, tl, br, bl;
q = malloc(rw*rh*PIXELSIZE);
//Bilinear interpolation for upscaling
for (y=0; y=sw) fxceil = sw-1;
if (fyceil>=sh) fyceil = sh-1;
tr = src[sw*(int)floor(fy)+fxceil];
tl = src[sw*(int)floor(fy)+(int)floor(fx)];
br = src[sw*fyceil+fxceil];
bl = src[sw*fyceil+(int)floor(fx)];
q[rw*y+x] = PIXRGB(
(int)(((((float)PIXR(tl))*(1.0f-fxc))+(((float)PIXR(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXR(bl))*(1.0f-fxc))+(((float)PIXR(br))*(fxc)))*(fyc)),
(int)(((((float)PIXG(tl))*(1.0f-fxc))+(((float)PIXG(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXG(bl))*(1.0f-fxc))+(((float)PIXG(br))*(fxc)))*(fyc)),
(int)(((((float)PIXB(tl))*(1.0f-fxc))+(((float)PIXB(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXB(bl))*(1.0f-fxc))+(((float)PIXB(br))*(fxc)))*(fyc))
);
}
} else {
//Stairstepping
float fx, fy, fyc, fxc;
double intp;
pixel tr, tl, br, bl;
int rrw = rw, rrh = rh;
pixel * oq;
oq = malloc(sw*sh*PIXELSIZE);
memcpy(oq, src, sw*sh*PIXELSIZE);
rw = sw;
rh = sh;
while(rrw != rw && rrh != rh){
rw *= 0.7;
rh *= 0.7;
if(rw <= rrw || rh <= rrh){
rw = rrw;
rh = rrh;
}
q = malloc(rw*rh*PIXELSIZE);
//Bilinear interpolation for upscaling
for (y=0; y=sw) fxceil = sw-1;
if (fyceil>=sh) fyceil = sh-1;
tr = oq[sw*(int)floor(fy)+fxceil];
tl = oq[sw*(int)floor(fy)+(int)floor(fx)];
br = oq[sw*fyceil+fxceil];
bl = oq[sw*fyceil+(int)floor(fx)];
q[rw*y+x] = PIXRGB(
(int)(((((float)PIXR(tl))*(1.0f-fxc))+(((float)PIXR(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXR(bl))*(1.0f-fxc))+(((float)PIXR(br))*(fxc)))*(fyc)),
(int)(((((float)PIXG(tl))*(1.0f-fxc))+(((float)PIXG(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXG(bl))*(1.0f-fxc))+(((float)PIXG(br))*(fxc)))*(fyc)),
(int)(((((float)PIXB(tl))*(1.0f-fxc))+(((float)PIXB(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXB(bl))*(1.0f-fxc))+(((float)PIXB(br))*(fxc)))*(fyc))
);
}
free(oq);
oq = q;
sw = rw;
sh = rh;
}
}
return q;
}
pixel *rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f)
{
int i,j,x,y,w,h,r,g,b,c;
pixel p, *q;
w = (sw+f-1)/f;
h = (sh+f-1)/f;
q = malloc(w*h*PIXELSIZE);
for (y=0; y1)
{
r = (r+c/2)/c;
g = (g+c/2)/c;
b = (b+c/2)/c;
}
q[y*w+x] = PIXRGB(r, g, b);
}
*qw = w;
*qh = h;
return q;
}
#ifdef OGLR
void clearScreen(float alpha)
{
if(alpha > 0.999f)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
else
{
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(XRES, 0);
glVertex2f(XRES, YRES);
glVertex2f(0, YRES);
glEnd();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlendEquation(GL_FUNC_ADD);
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void clearScreenNP(float alpha)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void ogl_blit(int x, int y, int w, int h, pixel *src, int pitch, int scale)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glDrawPixels(w,h,GL_BGRA,GL_UNSIGNED_BYTE,src); //Why does this still think it's ABGR?
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, vidBuf);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES+BARSIZE, YRES+MENUSIZE, GL_BGRA, GL_UNSIGNED_BYTE, src);
glBegin(GL_QUADS);
glTexCoord2d(1, 0);
glVertex3f((XRES+BARSIZE)*sdl_scale, (YRES+MENUSIZE)*sdl_scale, 1.0);
glTexCoord2d(0, 0);
glVertex3f(0, (YRES+MENUSIZE)*sdl_scale, 1.0);
glTexCoord2d(0, 1);
glVertex3f(0, 0, 1.0);
glTexCoord2d(1, 1);
glVertex3f((XRES+BARSIZE)*sdl_scale, 0, 1.0);
glEnd();
glDisable( GL_TEXTURE_2D );
glBlendFunc(GL_ONE, GL_ONE);
glFlush();
SDL_GL_SwapBuffers ();
}
#endif
void sdl_blit_1(int x, int y, int w, int h, pixel *src, int pitch)
{
pixel *dst;
int j;
if (SDL_MUSTLOCK(sdl_scrn))
if (SDL_LockSurface(sdl_scrn)<0)
return;
dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
if (SDL_MapRGB(sdl_scrn->format,0x33,0x55,0x77)!=PIXPACK(0x335577))
{
//pixel format conversion
int i;
pixel px;
SDL_PixelFormat *fmt = sdl_scrn->format;
for (j=0; j>fmt->Rloss)<Rshift)|
((PIXG(px)>>fmt->Gloss)<Gshift)|
((PIXB(px)>>fmt->Bloss)<Bshift);
}
dst+=sdl_scrn->pitch/PIXELSIZE;
src+=pitch;
}
}
else
{
for (j=0; jpitch/PIXELSIZE;
src+=pitch;
}
}
if (SDL_MUSTLOCK(sdl_scrn))
SDL_UnlockSurface(sdl_scrn);
SDL_UpdateRect(sdl_scrn,0,0,0,0);
}
void sdl_blit_2(int x, int y, int w, int h, pixel *src, int pitch)
{
pixel *dst;
int j;
int i,k;
if (SDL_MUSTLOCK(sdl_scrn))
if (SDL_LockSurface(sdl_scrn)<0)
return;
dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
if (SDL_MapRGB(sdl_scrn->format,0x33,0x55,0x77)!=PIXPACK(0x335577))
{
//pixel format conversion
pixel px;
SDL_PixelFormat *fmt = sdl_scrn->format;
for (j=0; j>fmt->Rloss)<Rshift)|
((PIXG(px)>>fmt->Gloss)<Gshift)|
((PIXB(px)>>fmt->Bloss)<Bshift);
dst[i*2]=px;
dst[i*2+1]=px;
}
dst+=sdl_scrn->pitch/PIXELSIZE;
}
src+=pitch;
}
}
else
{
for (j=0; jpitch/PIXELSIZE;
}
src+=pitch;
}
}
if (SDL_MUSTLOCK(sdl_scrn))
SDL_UnlockSurface(sdl_scrn);
SDL_UpdateRect(sdl_scrn,0,0,0,0);
}
void sdl_blit(int x, int y, int w, int h, pixel *src, int pitch)
{
#if defined(OGLR)
ogl_blit(x, y, w, h, src, pitch, sdl_scale);
#else
if (sdl_scale == 2)
sdl_blit_2(x, y, w, h, src, pitch);
else
sdl_blit_1(x, y, w, h, src, pitch);
#endif
}
//an easy way to draw a blob
void drawblob(pixel *vid, int x, int y, unsigned char cr, unsigned char cg, unsigned char cb)
{
blendpixel(vid, x+1, y, cr, cg, cb, 112);
blendpixel(vid, x-1, y, cr, cg, cb, 112);
blendpixel(vid, x, y+1, cr, cg, cb, 112);
blendpixel(vid, x, y-1, cr, cg, cb, 112);
blendpixel(vid, x+1, y-1, cr, cg, cb, 64);
blendpixel(vid, x-1, y-1, cr, cg, cb, 64);
blendpixel(vid, x+1, y+1, cr, cg, cb, 64);
blendpixel(vid, x-1, y+1, cr, cg, cb, 64);
}
//draws walls and elements for menu
int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc)
{
int i, j, c;
pixel gc;
if (x > XRES-26 || x < 0)
return 26;
if ((b&0xFF) == PT_LIFE)
{
for (j=1; j<15; j++)
{
for (i=1; i<27; i++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
c = PIXB(pc) + 3*PIXG(pc) + 2*PIXR(pc);
if (c<544)
{
c = 255;
}
else
{
c = 0;
}
drawtext(vid_buf, x+14-textwidth((char *)gmenu[(b>>8)&0xFF].name)/2, y+4, (char *)gmenu[(b>>8)&0xFF].name, c, c, c, 255);
}
else if (b>=UI_WALLSTART)
{
int ds = 0;
if (b-UI_WALLSTART>=0 && b-UI_WALLSTART>1)); i<27; i+=2)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
else if (ds==2)
{
for (j=1; j<15; j+=2)
for (i=1; i<27; i+=2)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
else if (ds==3)
{
for (j=1; j<15; j++)
for (i=1; i<27; i++)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
else if (ds==4)
{
for (j=1; j<15; j++)
for (i=1; i<27; i++)
if(i%CELL == j%CELL)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
else if (i%CELL == (j%CELL)+1 || (i%CELL == 0 && j%CELL == CELL-1))
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = gc;
else
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = PIXPACK(0x202020);
}
else
switch (b)
{
case WL_WALLELEC+100:
for (j=1; j<15; j++)
{
for (i=1; i<27; i++)
{
if (!(i%2) && !(j%2))
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
else
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = PIXPACK(0x808080);
}
}
}
break;
case WL_EWALL+100:
for (j=1; j<15; j++)
{
for (i=1; i<6+j; i++)
{
if (!(i&j&1))
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
for (; i<27; i++)
{
if (i&j&1)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
}
break;
case WL_STREAM+100:
for (j=1; j<15; j++)
{
for (i=1; i<27; i++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = i==1||i==26||j==1||j==14 ? PIXPACK(0xA0A0A0) : PIXPACK(0x000000);
drawtext(vid_buf, x+4, y+3, "\x8D", 255, 255, 255, 255);
}
}
for (i=9; i<27; i++)
{
drawpixel(vid_buf, x+i, y+8+(int)(3.9f*cos(i*0.3f)), 255, 255, 255, 255);
}
break;
case WL_SIGN+100:
for (j=1; j<15; j++)
{
for (i=1; i<27; i++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = i==1||i==26||j==1||j==14 ? PIXPACK(0xA0A0A0) : PIXPACK(0x000000);
}
}
drawtext(vid_buf, x+9, y+3, "\xA1", 32, 64, 128, 255);
drawtext(vid_buf, x+9, y+3, "\xA0", 255, 255, 255, 255);
break;
case WL_ERASE+100:
for (j=1; j<15; j+=2)
{
for (i=1+(1&(j>>1)); i<13; i+=2)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
for (j=1; j<15; j++)
{
for (i=14; i<27; i++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
break;
case SPC_AIR:
case SPC_HEAT:
case SPC_COOL:
case SPC_VACUUM:
case SPC_WIND:
case SPC_PGRV:
case SPC_NGRV:
case SPC_PROP:
for (j=1; j<15; j++)
for (i=1; i<27; i++)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
c = PIXR(pc) + 3*PIXG(pc) + 2*PIXB(pc);
if (c<544)
{
c = 255;
}
else
{
c = 0;
}
if (b==SPC_AIR)
drawtext(vid_buf, x+14-textwidth("AIR")/2, y+4, "AIR", c, c, c, 255);
else if (b==SPC_HEAT)
drawtext(vid_buf, x+14-textwidth("HEAT")/2, y+4, "HEAT", c, c, c, 255);
else if (b==SPC_COOL)
drawtext(vid_buf, x+14-textwidth("COOL")/2, y+4, "COOL", c, c, c, 255);
else if (b==SPC_VACUUM)
drawtext(vid_buf, x+14-textwidth("VAC")/2, y+4, "VAC", c, c, c, 255);
else if (b==SPC_WIND)
drawtext(vid_buf, x+14-textwidth("WIND")/2, y+4, "WIND", c, c, c, 255);
else if (b==SPC_PGRV)
drawtext(vid_buf, x+14-textwidth("PGRV")/2, y+4, "PGRV", c, c, c, 255);
else if (b==SPC_NGRV)
drawtext(vid_buf, x+14-textwidth("NGRV")/2, y+4, "NGRV", c, c, c, 255);
else if (b==SPC_PROP)
drawtext(vid_buf, x+14-textwidth("PROP")/2, y+4, "PROP", c, c, c, 255);
break;
default:
for (j=1; j<15; j++)
for (i=1; i<27; i++)
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
if (b==WL_ERASE+100)
{
for (j=4; j<12; j++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+j+6)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x+j+7)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x-j+21)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x-j+22)] = PIXPACK(0xFF0000);
}
}
}
else
{
//x = 2+32*(b/2);
//y = YRES+2+20*(b%2);
for (j=1; j<15; j++)
{
for (i=1; i<27; i++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc;
}
}
if (b==0)
{
for (j=4; j<12; j++)
{
vid_buf[(XRES+BARSIZE)*(y+j)+(x+j+6)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x+j+7)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x-j+21)] = PIXPACK(0xFF0000);
vid_buf[(XRES+BARSIZE)*(y+j)+(x-j+22)] = PIXPACK(0xFF0000);
}
}
c = PIXB(ptypes[b].pcolors) + 3*PIXG(ptypes[b].pcolors) + 2*PIXR(ptypes[b].pcolors);
if (c<544)
{
c = 255;
}
else
{
c = 0;
}
drawtext(vid_buf, x+14-textwidth((char *)ptypes[b].name)/2, y+4, (char *)ptypes[b].name, c, c, c, 255);
}
return 26;
}
void draw_menu(pixel *vid_buf, int i, int hover)
{
if (i==SEC&&SEC!=0)
drawrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 0, 255, 255, 255);
else
drawrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255);
if (hover==i)
{
fillrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(SC_TOTAL*16), 14, 14, 255, 255, 255, 255);
drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 0, 0, 0, 255);
}
else
{
drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(SC_TOTAL*16), msections[i].icon, 255, 255, 255, 255);
}
}
void draw_color_menu(pixel *vid_buf, int i, int hover)
{
drawrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(DECO_SECTIONS*16), 14, 14, 255, 255, 255, 255);
if (hover==i)
{
fillrect(vid_buf, (XRES+BARSIZE)-16, (i*16)+YRES+MENUSIZE-16-(DECO_SECTIONS*16), 14, 14, 255, 255, 255, 255);
drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(DECO_SECTIONS*16), colorsections[i].icon, 0, 0, 0, 255);
}
else
{
drawtext(vid_buf, (XRES+BARSIZE)-13, (i*16)+YRES+MENUSIZE-14-(DECO_SECTIONS*16), colorsections[i].icon, 255, 255, 255, 255);
}
}
//draws a pixel, identical to blendpixel(), except blendpixel has OpenGL support
#if defined(WIN32) && !defined(__GNUC__)
_inline void drawpixel(pixel *vid, int x, int y, int r, int g, int b, int a)
#else
inline void drawpixel(pixel *vid, int x, int y, int r, int g, int b, int a)
#endif
{
#ifdef PIXALPHA
pixel t;
if (x<0 || y<0 || x>=XRES+BARSIZE || y>=YRES+MENUSIZE)
return;
if (a!=255)
{
t = vid[y*(XRES+BARSIZE)+x];
r = (a*r + (255-a)*PIXR(t)) >> 8;
g = (a*g + (255-a)*PIXG(t)) >> 8;
b = (a*b + (255-a)*PIXB(t)) >> 8;
a = a > PIXA(t) ? a : PIXA(t);
}
vid[y*(XRES+BARSIZE)+x] = PIXRGBA(r,g,b,a);
#else
pixel t;
if (x<0 || y<0 || x>=XRES+BARSIZE || y>=YRES+MENUSIZE)
return;
if (a!=255)
{
t = vid[y*(XRES+BARSIZE)+x];
r = (a*r + (255-a)*PIXR(t)) >> 8;
g = (a*g + (255-a)*PIXG(t)) >> 8;
b = (a*b + (255-a)*PIXB(t)) >> 8;
}
vid[y*(XRES+BARSIZE)+x] = PIXRGB(r,g,b);
#endif
}
#if defined(WIN32) && !defined(__GNUC__)
_inline int drawchar(pixel *vid, int x, int y, int c, int r, int g, int b, int a)
#else
inline int drawchar(pixel *vid, int x, int y, int c, int r, int g, int b, int a)
#endif
{
int i, j, w, bn = 0, ba = 0;
char *rp = font_data + font_ptrs[c];
w = *(rp++);
for (j=0; j>= 2;
bn -= 2;
}
return x + w;
}
int addchar(pixel *vid, int x, int y, int c, int r, int g, int b, int a)
{
int i, j, w, bn = 0, ba = 0;
char *rp = font_data + font_ptrs[c];
w = *(rp++);
for (j=0; j>= 2;
bn -= 2;
}
return x + w;
}
int drawtext(pixel *vid, int x, int y, const char *s, int r, int g, int b, int a)
{
int sx = x;
for (; *s; s++)
{
if (*s == '\n')
{
x = sx;
y += FONT_H+2;
}
else if (*s == '\b')
{
switch (s[1])
{
case 'w':
r = g = b = 255;
break;
case 'g':
r = g = b = 192;
break;
case 'o':
r = 255;
g = 216;
b = 32;
break;
case 'r':
r = 255;
g = b = 0;
break;
case 'l':
r = 255;
g = b = 75;
break;
case 'b':
r = g = 0;
b = 255;
break;
case 't':
b = 255;
g = 170;
r = 32;
break;
}
s++;
}
else
x = drawchar(vid, x, y, *(unsigned char *)s, r, g, b, a);
}
return x;
}
//Draw text with an outline
int drawtext_outline(pixel *vid, int x, int y, const char *s, int r, int g, int b, int a, int or, int og, int ob, int oa)
{
drawtext(vid, x-1, y-1, s, or, og, ob, oa);
drawtext(vid, x+1, y+1, s, or, og, ob, oa);
drawtext(vid, x-1, y+1, s, or, og, ob, oa);
drawtext(vid, x+1, y-1, s, or, og, ob, oa);
return drawtext(vid, x, y, s, r, g, b, a);
}
int drawtextwrap(pixel *vid, int x, int y, int w, const char *s, int r, int g, int b, int a)
{
int sx = x;
int rh = 12;
int rw = 0;
int cw = x;
int wordlen;
int charspace;
while (*s)
{
wordlen = strcspn(s," .,!?\n");
charspace = textwidthx((char *)s, w-(x-cw));
if (charspace=-1; s++)
{
if (*s == '\n')
{
x = sx;
rw = 0;
y += FONT_H+2;
}
else if (*s == '\b')
{
switch (s[1])
{
case 'w':
r = g = b = 255;
break;
case 'g':
r = g = b = 192;
break;
case 'o':
r = 255;
g = 216;
b = 32;
break;
case 'r':
r = 255;
g = b = 0;
break;
case 'l':
r = 255;
g = b = 75;
break;
case 'b':
r = g = 0;
b = 255;
break;
case 't':
b = 255;
g = 170;
r = 32;
break;
}
s++;
}
else
{
if (x-cw>=w)
{
x = sx;
rw = 0;
y+=FONT_H+2;
rh+=FONT_H+2;
if (*s==' ')
continue;
}
x = drawchar(vid, x, y, *(unsigned char *)s, r, g, b, a);
}
}
}
return rh;
}
//draws a rectange, (x,y) are the top left coords.
void drawrect(pixel *vid, int x, int y, int w, int h, int r, int g, int b, int a)
{
int i;
for (i=0; i<=w; i++)
{
drawpixel(vid, x+i, y, r, g, b, a);
drawpixel(vid, x+i, y+h, r, g, b, a);
}
for (i=1; i=w && x+textwidth(s)>=w+5)
break;
x = drawchar(vid, x, y, *(unsigned char *)s, r, g, b, a);
}
if (*s)
for (i=0; i<3; i++)
x = drawchar(vid, x, y, '.', r, g, b, a);
return x;
}
int textnwidth(char *s, int n)
{
int x = 0;
for (; *s; s++)
{
if (!n)
break;
x += font_data[font_ptrs[(int)(*(unsigned char *)s)]];
n--;
}
return x-1;
}
void textnpos(char *s, int n, int w, int *cx, int *cy)
{
int x = 0;
int y = 0;
int wordlen, charspace;
while (*s&&n)
{
wordlen = strcspn(s," .,!?\n");
charspace = textwidthx(s, w-x);
if (charspace=-1; s++)
{
if (!n) {
break;
}
x += font_data[font_ptrs[(int)(*(unsigned char *)s)]];
if (x>=w)
{
x = 0;
y += FONT_H+2;
if (*(s+1)==' ')
x -= font_data[font_ptrs[(int)(' ')]];
}
n--;
}
}
*cx = x-1;
*cy = y;
}
int textwidthx(char *s, int w)
{
int x=0,n=0,cw;
for (; *s; s++)
{
cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]];
if (x+(cw/2) >= w)
break;
x += cw;
n++;
}
return n;
}
int textposxy(char *s, int width, int w, int h)
{
int x=0,y=0,n=0,cw, wordlen, charspace;
while (*s)
{
wordlen = strcspn(s," .,!?\n");
charspace = textwidthx(s, width-x);
if (charspace=-1; s++)
{
cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]];
if ((x+(cw/2) >= w && y+6 >= h)||(y+6 >= h+FONT_H+2))
return n++;
x += cw;
if (x>=width) {
x = 0;
y += FONT_H+2;
if (*(s+1)==' ')
x -= font_data[font_ptrs[(int)(' ')]];
}
n++;
}
}
return n;
}
int textwrapheight(char *s, int width)
{
int x=0, height=FONT_H+2, cw;
int wordlen;
int charspace;
while (*s)
{
wordlen = strcspn(s," .,!?\n");
charspace = textwidthx(s, width-x);
if (charspace=-1; s++)
{
if (*s == '\n')
{
x = 0;
height += FONT_H+2;
}
else if (*s == '\b')
{
s++;
}
else
{
cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]];
if (x+cw>=width)
{
x = 0;
height += FONT_H+2;
if (*s==' ')
continue;
}
x += cw;
}
}
}
return height;
}
//the most used function for drawing a pixel, because it has OpenGL support, which is not fully implemented.
#if defined(WIN32) && !defined(__GNUC__)
_inline void blendpixel(pixel *vid, int x, int y, int r, int g, int b, int a)
#else
inline void blendpixel(pixel *vid, int x, int y, int r, int g, int b, int a)
#endif
{
#ifdef PIXALPHA
pixel t;
if (x<0 || y<0 || x>=XRES+BARSIZE || y>=YRES+MENUSIZE)
return;
if (a!=255)
{
t = vid[y*(XRES+BARSIZE)+x];
r = (a*r + (255-a)*PIXR(t)) >> 8;
g = (a*g + (255-a)*PIXG(t)) >> 8;
b = (a*b + (255-a)*PIXB(t)) >> 8;
a = a > PIXA(t) ? a : PIXA(t);
}
vid[y*(XRES+BARSIZE)+x] = PIXRGBA(r,g,b,a);
#else
pixel t;
if (x<0 || y<0 || x>=XRES+BARSIZE || y>=YRES+MENUSIZE)
return;
if (a!=255)
{
t = vid[y*(XRES+BARSIZE)+x];
r = (a*r + (255-a)*PIXR(t)) >> 8;
g = (a*g + (255-a)*PIXG(t)) >> 8;
b = (a*b + (255-a)*PIXB(t)) >> 8;
}
vid[y*(XRES+BARSIZE)+x] = PIXRGB(r,g,b);
#endif
}
void draw_icon(pixel *vid_buf, int x, int y, char ch, int flag)
{
char t[2];
t[0] = ch;
t[1] = 0;
if (flag)
{
fillrect(vid_buf, x-1, y-1, 17, 17, 255, 255, 255, 255);
drawtext(vid_buf, x+3, y+2, t, 0, 0, 0, 255);
}
else
{
drawrect(vid_buf, x, y, 15, 15, 255, 255, 255, 255);
drawtext(vid_buf, x+3, y+2, t, 255, 255, 255, 255);
}
}
void draw_air(pixel *vid)
{
#ifndef OGLR
int x, y, i, j;
pixel c;
for (y=0; y 0.0f)
c = PIXRGB(clamp_flt(pv[y][x], 0.0f, 8.0f), 0, 0);//positive pressure is red!
else
c = PIXRGB(0, 0, clamp_flt(-pv[y][x], 0.0f, 8.0f));//negative pressure is blue!
}
else if (display_mode & DISPLAY_AIRV)
{
c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
clamp_flt(pv[y][x], 0.0f, 8.0f),//pressure adds green
clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue
}
else if ((display_mode & DISPLAY_AIRH))
{
if (aheat_enable)
{
float ttemp = hv[y][x]+(-MIN_TEMP);
int caddress = restrict_flt((int)( restrict_flt(ttemp, 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/1024) ) *3, 0.0f, (1024.0f*3)-3);
c = PIXRGB((int)((unsigned char)color_data[caddress]*0.7f), (int)((unsigned char)color_data[caddress+1]*0.7f), (int)((unsigned char)color_data[caddress+2]*0.7f));
//c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
// clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green
// clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue
}
else
c = PIXRGB(0,0,0);
}
else if (display_mode & DISPLAY_AIRC)
{
int r;
int g;
int b;
// velocity adds grey
r = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f);
g = clamp_flt(fabsf(vx[y][x]), 0.0f, 20.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 24.0f);
b = clamp_flt(fabsf(vx[y][x]), 0.0f, 24.0f) + clamp_flt(fabsf(vy[y][x]), 0.0f, 20.0f);
if (pv[y][x] > 0.0f)
{
r += clamp_flt(pv[y][x], 0.0f, 16.0f);//pressure adds red!
if (r>255)
r=255;
if (g>255)
g=255;
if (b>255)
b=255;
c = PIXRGB(r, g, b);
}
else
{
b += clamp_flt(-pv[y][x], 0.0f, 16.0f);//pressure adds blue!
if (r>255)
r=255;
if (g>255)
g=255;
if (b>255)
b=255;
c = PIXRGB(r, g, b);
}
}
for (j=0; jdx)
{
dx = dx+dy;
dy = dx-dy;
dx = dx-dy;
check = 1;
}
e = (dy<<2)-dx;
for (i=0; i<=dx; i++)
{
if (x>=0 && y>=0 && x=0)
{
if (check==1)
x = x+sx;
else
y = y+sy;
e = e-(dx<<2);
}
if (check==1)
y = y+sy;
else
x = x+sx;
e = e+(dy<<2);
}
}
//adds color to a pixel, does not overwrite.
void addpixel(pixel *vid, int x, int y, int r, int g, int b, int a)
{
pixel t;
if (x<0 || y<0 || x>=XRES+BARSIZE || y>=YRES+MENUSIZE)
return;
t = vid[y*(XRES+BARSIZE)+x];
r = (a*r + 255*PIXR(t)) >> 8;
g = (a*g + 255*PIXG(t)) >> 8;
b = (a*b + 255*PIXB(t)) >> 8;
if (r>255)
r = 255;
if (g>255)
g = 255;
if (b>255)
b = 255;
vid[y*(XRES+BARSIZE)+x] = PIXRGB(r,g,b);
}
//draws one of two colors, so that it is always clearly visible
void xor_pixel(int x, int y, pixel *vid)
{
int c;
if (x<0 || y<0 || x>=XRES || y>=YRES)
return;
c = vid[y*(XRES+BARSIZE)+x];
c = PIXB(c) + 3*PIXG(c) + 2*PIXR(c);
if (c<512)
vid[y*(XRES+BARSIZE)+x] = PIXPACK(0xC0C0C0);
else
vid[y*(XRES+BARSIZE)+x] = PIXPACK(0x404040);
}
//same as xor_pixel, but draws a line of it
void xor_line(int x1, int y1, int x2, int y2, pixel *vid)
{
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
float e, de;
if (cp)
{
y = x1;
x1 = y1;
y1 = y;
y = x2;
x2 = y2;
y2 = y;
}
if (x1 > x2)
{
y = x1;
x1 = x2;
x2 = y;
y = y1;
y1 = y2;
y2 = y;
}
dx = x2 - x1;
dy = abs(y2 - y1);
e = 0.0f;
if (dx)
de = dy/(float)dx;
else
de = 0.0f;
y = y1;
sy = (y1= 0.5f)
{
y += sy;
e -= 1.0f;
}
}
}
//same as blend_pixel, but draws a line of it
void blend_line(pixel *vid, int x1, int y1, int x2, int y2, int r, int g, int b, int a)
{
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
float e, de;
if (cp)
{
y = x1;
x1 = y1;
y1 = y;
y = x2;
x2 = y2;
y2 = y;
}
if (x1 > x2)
{
y = x1;
x1 = x2;
x2 = y;
y = y1;
y1 = y2;
y2 = y;
}
dx = x2 - x1;
dy = abs(y2 - y1);
e = 0.0f;
if (dx)
de = dy/(float)dx;
else
de = 0.0f;
y = y1;
sy = (y1= 0.5f)
{
y += sy;
e -= 1.0f;
}
}
}
//same as xor_pixel, but draws a rectangle
void xor_rect(pixel *vid, int x, int y, int w, int h)
{
int i;
for (i=0; i0 && !sys_pause) emp_decor-=emp_decor/25+2;
if (emp_decor>40) emp_decor=40;
if (emp_decor<0) emp_decor = 0;
if (!(render_mode & EFFECT)) // not in nothing mode
return;
if (emp_decor>0)
{
#ifdef OGLR
float femp_decor = ((float)emp_decor)/255.0f;
/*int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255;
int a=(1.0*emp_decor/110)*255;
if (r>255) r=255;
if (g>255) g=255;
if (b>255) g=255;
if (a>255) a=255;*/
glBegin(GL_QUADS);
glColor4f(femp_decor*2.5f, 0.4f+femp_decor*1.5f, 1.0f+femp_decor*1.5f, femp_decor/0.44f);
glVertex2f(0, MENUSIZE);
glVertex2f(XRES, MENUSIZE);
glVertex2f(XRES, YRES+MENUSIZE);
glVertex2f(0, YRES+MENUSIZE);
glEnd();
#else
int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255;
int a=(1.0*emp_decor/110)*255;
if (r>255) r=255;
if (g>255) g=255;
if (b>255) g=255;
if (a>255) a=255;
for (j=0; j>24)&0xFF;
decr = (parts[i].dcolour>>16)&0xFF;
decg = (parts[i].dcolour>>8)&0xFF;
decb = (parts[i].dcolour)&0xFF;
/*if(display_mode == RENDER_NONE)
{
if(decorations_enable)
{
colr = (deca*decr + (255-deca)*colr) >> 8;
colg = (deca*decg + (255-deca)*colg) >> 8;
colb = (deca*decb + (255-deca)*colb) >> 8;
}
#ifdef OGLR
flatV[cflatV++] = nx;
flatV[cflatV++] = ny;
flatC[cflatC++] = ((float)colr)/255.0f;
flatC[cflatC++] = ((float)colg)/255.0f;
flatC[cflatC++] = ((float)colb)/255.0f;
flatC[cflatC++] = 1.0f;
cflat++;
#else
vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb);
#endif
}
else*/
{
if (graphicscache[t].isready)
{
pixel_mode = graphicscache[t].pixel_mode;
cola = graphicscache[t].cola;
colr = graphicscache[t].colr;
colg = graphicscache[t].colg;
colb = graphicscache[t].colb;
firea = graphicscache[t].firea;
firer = graphicscache[t].firer;
fireg = graphicscache[t].fireg;
fireb = graphicscache[t].fireb;
}
else if(!(colour_mode & COLOUR_BASC)) //Don't get special effects for BASIC colour mode
{
#ifdef LUACONSOLE
if (lua_gr_func[t])
{
if (luacon_graphics_update(t,i, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb))
{
graphicscache[t].isready = 1;
graphicscache[t].pixel_mode = pixel_mode;
graphicscache[t].cola = cola;
graphicscache[t].colr = colr;
graphicscache[t].colg = colg;
graphicscache[t].colb = colb;
graphicscache[t].firea = firea;
graphicscache[t].firer = firer;
graphicscache[t].fireg = fireg;
graphicscache[t].fireb = fireb;
}
}
else if (ptypes[t].graphics_func)
{
#else
if (ptypes[t].graphics_func)
{
#endif
if ((*(ptypes[t].graphics_func))(&(parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb)) //That's a lot of args, a struct might be better
{
graphicscache[t].isready = 1;
graphicscache[t].pixel_mode = pixel_mode;
graphicscache[t].cola = cola;
graphicscache[t].colr = colr;
graphicscache[t].colg = colg;
graphicscache[t].colb = colb;
graphicscache[t].firea = firea;
graphicscache[t].firer = firer;
graphicscache[t].fireg = fireg;
graphicscache[t].fireb = fireb;
}
}
else
{
if(graphics_DEFAULT(&(parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb))
{
graphicscache[t].isready = 1;
graphicscache[t].pixel_mode = pixel_mode;
graphicscache[t].cola = cola;
graphicscache[t].colr = colr;
graphicscache[t].colg = colg;
graphicscache[t].colb = colb;
graphicscache[t].firea = firea;
graphicscache[t].firer = firer;
graphicscache[t].fireg = fireg;
graphicscache[t].fireb = fireb;
}
}
}
if(ptypes[t].properties & PROP_HOT_GLOW && parts[i].temp>(ptransitions[t].thv-800.0f))
{
gradv = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f));
caddress = (parts[i].temp>ptransitions[t].thv)?ptransitions[t].thv-(ptransitions[t].thv-800.0f):parts[i].temp-(ptransitions[t].thv-800.0f);
colr += sin(gradv*caddress) * 226;;
colg += sin(gradv*caddress*4.55 +3.14) * 34;
colb += sin(gradv*caddress*2.22 +3.14) * 64;
}
if(pixel_mode & FIRE_ADD && !(render_mode & FIRE_ADD))
pixel_mode |= PMODE_GLOW;
if(pixel_mode & FIRE_BLEND && !(render_mode & FIRE_BLEND))
pixel_mode |= PMODE_BLUR;
if(pixel_mode & PMODE_BLUR && !(render_mode & PMODE_BLUR))
pixel_mode |= PMODE_FLAT;
if(pixel_mode & PMODE_GLOW && !(render_mode & PMODE_GLOW))
pixel_mode |= PMODE_BLEND;
if (render_mode & PMODE_BLOB)
pixel_mode |= PMODE_BLOB;
pixel_mode &= render_mode;
//Alter colour based on display mode
if(colour_mode & COLOUR_HEAT)
{
caddress = restrict_flt((int)( restrict_flt((float)(parts[i].temp+(-MIN_TEMP)), 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/1024) ) *3, 0.0f, (1024.0f*3)-3);
firea = 255;
firer = colr = (unsigned char)color_data[caddress];
fireg = colg = (unsigned char)color_data[caddress+1];
fireb = colb = (unsigned char)color_data[caddress+2];
cola = 255;
if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
}
else if(colour_mode & COLOUR_LIFE)
{
gradv = 0.4f;
if (!(parts[i].life<5))
q = sqrt(parts[i].life);
else
q = parts[i].life;
colr = colg = colb = sin(gradv*q) * 100 + 128;
cola = 255;
if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
}
else if (colour_mode & COLOUR_BASC)
{
colr = PIXR(ptypes[t].pcolors);
colg = PIXG(ptypes[t].pcolors);
colb = PIXB(ptypes[t].pcolors);
pixel_mode = PMODE_FLAT;
}
//Apply decoration colour
if(!(colour_mode & ~COLOUR_GRAD))
{
if(!(pixel_mode & NO_DECO) && decorations_enable)
{
colr = (deca*decr + (255-deca)*colr) >> 8;
colg = (deca*decg + (255-deca)*colg) >> 8;
colb = (deca*decb + (255-deca)*colb) >> 8;
}
if(pixel_mode & DECO_FIRE && decorations_enable)
{
firer = (deca*decr + (255-deca)*firer) >> 8;
fireg = (deca*decg + (255-deca)*fireg) >> 8;
fireb = (deca*decb + (255-deca)*fireb) >> 8;
}
}
if (colour_mode & COLOUR_GRAD)
{
float frequency = 0.05;
int q = parts[i].temp-40;
colr = sin(frequency*q) * 16 + colr;
colg = sin(frequency*q) * 16 + colg;
colb = sin(frequency*q) * 16 + colb;
if(pixel_mode & (FIREMODE | PMODE_GLOW)) pixel_mode = (pixel_mode & ~(FIREMODE|PMODE_GLOW)) | PMODE_BLUR;
}
#ifndef OGLR
//All colours are now set, check ranges
if(colr>255) colr = 255;
else if(colr<0) colr = 0;
if(colg>255) colg = 255;
else if(colg<0) colg = 0;
if(colb>255) colb = 255;
else if(colb<0) colb = 0;
if(cola>255) cola = 255;
else if(cola<0) cola = 0;
if(firer>255) firer = 255;
else if(firer<0) firer = 0;
if(fireg>255) fireg = 255;
else if(fireg<0) fireg = 0;
if(fireb>255) fireb = 255;
else if(fireb<0) fireb = 0;
if(firea>255) firea = 255;
else if(firea<0) firea = 0;
#endif
//Pixel rendering
if (t==PT_SOAP)
{
if ((parts[i].ctype&7) == 7)
draw_line(vid, nx, ny, (int)(parts[parts[i].tmp].x+0.5f), (int)(parts[parts[i].tmp].y+0.5f), colr, colg, colb, XRES+BARSIZE);
}
if(pixel_mode & PSPEC_STICKMAN)
{
char buff[20]; //Buffer for HP
int s;
int legr, legg, legb;
playerst *cplayer;
if(t==PT_STKM)
cplayer = &player;
else if(t==PT_STKM2)
cplayer = &player2;
else if(t==PT_FIGH)
cplayer = &fighters[(unsigned char)parts[i].tmp];
else
continue;
if (mousex>(nx-3) && mousex<(nx+3) && mousey<(ny+3) && mousey>(ny-3)) //If mous is in the head
{
sprintf(buff, "%3d", parts[i].life); //Show HP
drawtext(vid, mousex-8-2*(parts[i].life<100)-2*(parts[i].life<10), mousey-12, buff, 255, 255, 255, 255);
}
if (colour_mode!=COLOUR_HEAT)
{
if (cplayer->elemelem].pcolors);
colg = PIXG(ptypes[cplayer->elem].pcolors);
colb = PIXB(ptypes[cplayer->elem].pcolors);
}
else
{
colr = 0x80;
colg = 0x80;
colb = 0xFF;
}
}
#ifdef OGLR
glColor4f(((float)colr)/255.0f, ((float)colg)/255.0f, ((float)colb)/255.0f, 1.0f);
glBegin(GL_LINE_STRIP);
if(t==PT_FIGH)
{
glVertex2f(fnx, fny+2);
glVertex2f(fnx+2, fny);
glVertex2f(fnx, fny-2);
glVertex2f(fnx-2, fny);
glVertex2f(fnx, fny+2);
}
else
{
glVertex2f(fnx-2, fny-2);
glVertex2f(fnx+2, fny-2);
glVertex2f(fnx+2, fny+2);
glVertex2f(fnx-2, fny+2);
glVertex2f(fnx-2, fny-2);
}
glEnd();
glBegin(GL_LINES);
if (colour_mode!=COLOUR_HEAT)
{
if (t==PT_STKM2)
glColor4f(100.0f/255.0f, 100.0f/255.0f, 1.0f, 1.0f);
else
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
glVertex2f(nx, ny+3);
glVertex2f(cplayer->legs[0], cplayer->legs[1]);
glVertex2f(cplayer->legs[0], cplayer->legs[1]);
glVertex2f(cplayer->legs[4], cplayer->legs[5]);
glVertex2f(nx, ny+3);
glVertex2f(cplayer->legs[8], cplayer->legs[9]);
glVertex2f(cplayer->legs[8], cplayer->legs[9]);
glVertex2f(cplayer->legs[12], cplayer->legs[13]);
glEnd();
#else
s = XRES+BARSIZE;
if (t==PT_STKM2)
{
legr = 100;
legg = 100;
legb = 255;
}
else
{
legr = 255;
legg = 255;
legb = 255;
}
if (colour_mode==COLOUR_HEAT)
{
legr = colr;
legg = colg;
legb = colb;
}
//head
if(t==PT_FIGH)
{
draw_line(vid , nx, ny+2, nx+2, ny, colr, colg, colb, s);
draw_line(vid , nx+2, ny, nx, ny-2, colr, colg, colb, s);
draw_line(vid , nx, ny-2, nx-2, ny, colr, colg, colb, s);
draw_line(vid , nx-2, ny, nx, ny+2, colr, colg, colb, s);
}
else
{
draw_line(vid , nx-2, ny+2, nx+2, ny+2, colr, colg, colb, s);
draw_line(vid , nx-2, ny-2, nx+2, ny-2, colr, colg, colb, s);
draw_line(vid , nx-2, ny-2, nx-2, ny+2, colr, colg, colb, s);
draw_line(vid , nx+2, ny-2, nx+2, ny+2, colr, colg, colb, s);
}
//legs
draw_line(vid , nx, ny+3, cplayer->legs[0], cplayer->legs[1], legr, legg, legb, s);
draw_line(vid , cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, s);
draw_line(vid , nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, s);
draw_line(vid , cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, s);
#endif
}
#ifdef OGLR
if((display_mode & DISPLAY_EFFE) && (fabs(fnx-flx)>1.5f || fabs(fny-fly)>1.5f))
{
if(pixel_mode & PMODE_FLAT)
{
blurLineV[cblurLineV++] = nx;
blurLineV[cblurLineV++] = ny;
blurLineC[cblurLineC++] = ((float)colr)/255.0f;
blurLineC[cblurLineC++] = ((float)colg)/255.0f;
blurLineC[cblurLineC++] = ((float)colb)/255.0f;
blurLineC[cblurLineC++] = 1.0f;
cblurLine++;
blurLineV[cblurLineV++] = flx;
blurLineV[cblurLineV++] = fly;
blurLineC[cblurLineC++] = ((float)colr)/255.0f;
blurLineC[cblurLineC++] = ((float)colg)/255.0f;
blurLineC[cblurLineC++] = ((float)colb)/255.0f;
blurLineC[cblurLineC++] = 0.0f;
cblurLine++;
}
else if(pixel_mode & PMODE_BLEND)
{
blurLineV[cblurLineV++] = nx;
blurLineV[cblurLineV++] = ny;
blurLineC[cblurLineC++] = ((float)colr)/255.0f;
blurLineC[cblurLineC++] = ((float)colg)/255.0f;
blurLineC[cblurLineC++] = ((float)colb)/255.0f;
blurLineC[cblurLineC++] = ((float)cola)/255.0f;
cblurLine++;
blurLineV[cblurLineV++] = flx;
blurLineV[cblurLineV++] = fly;
blurLineC[cblurLineC++] = ((float)colr)/255.0f;
blurLineC[cblurLineC++] = ((float)colg)/255.0f;
blurLineC[cblurLineC++] = ((float)colb)/255.0f;
blurLineC[cblurLineC++] = 0.0f;
cblurLine++;
}
else if(pixel_mode & PMODE_ADD)
{
ablurLineV[cablurLineV++] = nx;
ablurLineV[cablurLineV++] = ny;
ablurLineC[cablurLineC++] = ((float)colr)/255.0f;
ablurLineC[cablurLineC++] = ((float)colg)/255.0f;
ablurLineC[cablurLineC++] = ((float)colb)/255.0f;
ablurLineC[cablurLineC++] = ((float)cola)/255.0f;
cablurLine++;
ablurLineV[cablurLineV++] = flx;
ablurLineV[cablurLineV++] = fly;
ablurLineC[cablurLineC++] = ((float)colr)/255.0f;
ablurLineC[cablurLineC++] = ((float)colg)/255.0f;
ablurLineC[cablurLineC++] = ((float)colb)/255.0f;
ablurLineC[cablurLineC++] = 0.0f;
cablurLine++;
}
}
#endif
if(pixel_mode & PMODE_FLAT)
{
#ifdef OGLR
flatV[cflatV++] = nx;
flatV[cflatV++] = ny;
flatC[cflatC++] = ((float)colr)/255.0f;
flatC[cflatC++] = ((float)colg)/255.0f;
flatC[cflatC++] = ((float)colb)/255.0f;
flatC[cflatC++] = 1.0f;
cflat++;
#else
vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb);
#endif
}
if(pixel_mode & PMODE_BLEND)
{
#ifdef OGLR
flatV[cflatV++] = nx;
flatV[cflatV++] = ny;
flatC[cflatC++] = ((float)colr)/255.0f;
flatC[cflatC++] = ((float)colg)/255.0f;
flatC[cflatC++] = ((float)colb)/255.0f;
flatC[cflatC++] = ((float)cola)/255.0f;
cflat++;
#else
blendpixel(vid, nx, ny, colr, colg, colb, cola);
#endif
}
if(pixel_mode & PMODE_ADD)
{
#ifdef OGLR
addV[caddV++] = nx;
addV[caddV++] = ny;
addC[caddC++] = ((float)colr)/255.0f;
addC[caddC++] = ((float)colg)/255.0f;
addC[caddC++] = ((float)colb)/255.0f;
addC[caddC++] = ((float)cola)/255.0f;
cadd++;
#else
addpixel(vid, nx, ny, colr, colg, colb, cola);
#endif
}
if(pixel_mode & PMODE_BLOB)
{
#ifdef OGLR
blobV[cblobV++] = nx;
blobV[cblobV++] = ny;
blobC[cblobC++] = ((float)colr)/255.0f;
blobC[cblobC++] = ((float)colg)/255.0f;
blobC[cblobC++] = ((float)colb)/255.0f;
blobC[cblobC++] = 1.0f;
cblob++;
#else
vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb);
blendpixel(vid, nx+1, ny, colr, colg, colb, 223);
blendpixel(vid, nx-1, ny, colr, colg, colb, 223);
blendpixel(vid, nx, ny+1, colr, colg, colb, 223);
blendpixel(vid, nx, ny-1, colr, colg, colb, 223);
blendpixel(vid, nx+1, ny-1, colr, colg, colb, 112);
blendpixel(vid, nx-1, ny-1, colr, colg, colb, 112);
blendpixel(vid, nx+1, ny+1, colr, colg, colb, 112);
blendpixel(vid, nx-1, ny+1, colr, colg, colb, 112);
#endif
}
if(pixel_mode & PMODE_GLOW)
{
int cola1 = (5*cola)/255;
#ifdef OGLR
glowV[cglowV++] = nx;
glowV[cglowV++] = ny;
glowC[cglowC++] = ((float)colr)/255.0f;
glowC[cglowC++] = ((float)colg)/255.0f;
glowC[cglowC++] = ((float)colb)/255.0f;
glowC[cglowC++] = 1.0f;
cglow++;
#else
addpixel(vid, nx, ny, colr, colg, colb, (192*cola)/255);
addpixel(vid, nx+1, ny, colr, colg, colb, (96*cola)/255);
addpixel(vid, nx-1, ny, colr, colg, colb, (96*cola)/255);
addpixel(vid, nx, ny+1, colr, colg, colb, (96*cola)/255);
addpixel(vid, nx, ny-1, colr, colg, colb, (96*cola)/255);
for (x = 1; x < 6; x++) {
addpixel(vid, nx, ny-x, colr, colg, colb, cola1);
addpixel(vid, nx, ny+x, colr, colg, colb, cola1);
addpixel(vid, nx-x, ny, colr, colg, colb, cola1);
addpixel(vid, nx+x, ny, colr, colg, colb, cola1);
for (y = 1; y < 6; y++) {
if(x + y > 7)
continue;
addpixel(vid, nx+x, ny-y, colr, colg, colb, cola1);
addpixel(vid, nx-x, ny+y, colr, colg, colb, cola1);
addpixel(vid, nx+x, ny+y, colr, colg, colb, cola1);
addpixel(vid, nx-x, ny-y, colr, colg, colb, cola1);
}
}
#endif
}
if(pixel_mode & PMODE_BLUR)
{
#ifdef OGLR
blurV[cblurV++] = nx;
blurV[cblurV++] = ny;
blurC[cblurC++] = ((float)colr)/255.0f;
blurC[cblurC++] = ((float)colg)/255.0f;
blurC[cblurC++] = ((float)colb)/255.0f;
blurC[cblurC++] = 1.0f;
cblur++;
#else
for (x=-3; x<4; x++)
{
for (y=-3; y<4; y++)
{
if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2))
blendpixel(vid, x+nx, y+ny, colr, colg, colb, 30);
if (abs(x)+abs(y) <=3 && abs(x)+abs(y))
blendpixel(vid, x+nx, y+ny, colr, colg, colb, 20);
if (abs(x)+abs(y) == 2)
blendpixel(vid, x+nx, y+ny, colr, colg, colb, 10);
}
}
#endif
}
if(pixel_mode & PMODE_SPARK)
{
flicker = rand()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx-5;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/30;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx+5;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny-5;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/30;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny+5;
cline++;
#else
gradv = 4*parts[i].life + flicker;
for (x = 0; gradv>0.5; x++) {
addpixel(vid, nx+x, ny, colr, colg, colb, gradv);
addpixel(vid, nx-x, ny, colr, colg, colb, gradv);
addpixel(vid, nx, ny+x, colr, colg, colb, gradv);
addpixel(vid, nx, ny-x, colr, colg, colb, gradv);
gradv = gradv/1.5f;
}
#endif
}
if(pixel_mode & PMODE_FLARE)
{
flicker = rand()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx-10;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/40;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx+10;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny-10;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/30;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny+10;
cline++;
#else
gradv = flicker + fabs(parts[i].vx)*17 + fabs(parts[i].vy)*17;
blendpixel(vid, nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) );
blendpixel(vid, nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
if (gradv>255) gradv=255;
blendpixel(vid, nx+1, ny-1, colr, colg, colb, gradv);
blendpixel(vid, nx-1, ny-1, colr, colg, colb, gradv);
blendpixel(vid, nx+1, ny+1, colr, colg, colb, gradv);
blendpixel(vid, nx-1, ny+1, colr, colg, colb, gradv);
for (x = 1; gradv>0.5; x++) {
addpixel(vid, nx+x, ny, colr, colg, colb, gradv);
addpixel(vid, nx-x, ny, colr, colg, colb, gradv);
addpixel(vid, nx, ny+x, colr, colg, colb, gradv);
addpixel(vid, nx, ny-x, colr, colg, colb, gradv);
gradv = gradv/1.2f;
}
#endif
}
if(pixel_mode & PMODE_LFLARE)
{
flicker = rand()%20;
#ifdef OGLR
//Oh god, this is awful
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx-70;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/30;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx+70;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny-70;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 1.0f - ((float)flicker)/50;
lineV[clineV++] = fnx;
lineV[clineV++] = fny;
cline++;
lineC[clineC++] = ((float)colr)/255.0f;
lineC[clineC++] = ((float)colg)/255.0f;
lineC[clineC++] = ((float)colb)/255.0f;
lineC[clineC++] = 0.0f;
lineV[clineV++] = fnx;
lineV[clineV++] = fny+70;
cline++;
#else
gradv = flicker + fabs(parts[i].vx)*17 + fabs(parts[i].vy)*17;
blendpixel(vid, nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) );
blendpixel(vid, nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
blendpixel(vid, nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) );
if (gradv>255) gradv=255;
blendpixel(vid, nx+1, ny-1, colr, colg, colb, gradv);
blendpixel(vid, nx-1, ny-1, colr, colg, colb, gradv);
blendpixel(vid, nx+1, ny+1, colr, colg, colb, gradv);
blendpixel(vid, nx-1, ny+1, colr, colg, colb, gradv);
for (x = 1; gradv>0.5; x++) {
addpixel(vid, nx+x, ny, colr, colg, colb, gradv);
addpixel(vid, nx-x, ny, colr, colg, colb, gradv);
addpixel(vid, nx, ny+x, colr, colg, colb, gradv);
addpixel(vid, nx, ny-x, colr, colg, colb, gradv);
gradv = gradv/1.01f;
}
#endif
}
if (pixel_mode & EFFECT_GRAVIN)
{
int nxo = 0;
int nyo = 0;
int r;
int fire_rv = 0;
float drad = 0.0f;
float ddist = 0.0f;
orbitalparts_get(parts[i].life, parts[i].ctype, orbd, orbl);
for (r = 0; r < 4; r++) {
ddist = ((float)orbd[r])/16.0f;
drad = (M_PI * ((float)orbl[r]) / 180.0f)*1.41f;
nxo = (int)(ddist*cos(drad));
nyo = (int)(ddist*sin(drad));
if (ny+nyo>0 && ny+nyo0 && nx+nxo0 && ny+nyo0 && nx+nxo> 8;
fire_g[ny/CELL][nx/CELL] = (firea*fireg + (255-firea)*fire_g[ny/CELL][nx/CELL]) >> 8;
fire_b[ny/CELL][nx/CELL] = (firea*fireb + (255-firea)*fire_b[ny/CELL][nx/CELL]) >> 8;
#endif
}
if(firea && (pixel_mode & FIRE_ADD))
{
#ifdef OGLR
fireV[cfireV++] = nx;
fireV[cfireV++] = ny;
fireC[cfireC++] = ((float)firer)/255.0f;
fireC[cfireC++] = ((float)fireg)/255.0f;
fireC[cfireC++] = ((float)fireb)/255.0f;
fireC[cfireC++] = ((float)firea)/255.0f;
cfire++;
#else
firea /= 8;
firer = ((firea*firer) >> 8) + fire_r[ny/CELL][nx/CELL];
fireg = ((firea*fireg) >> 8) + fire_g[ny/CELL][nx/CELL];
fireb = ((firea*fireb) >> 8) + fire_b[ny/CELL][nx/CELL];
if(firer>255)
firer = 255;
if(fireg>255)
fireg = 255;
if(fireb>255)
fireb = 255;
fire_r[ny/CELL][nx/CELL] = firer;
fire_g[ny/CELL][nx/CELL] = fireg;
fire_b[ny/CELL][nx/CELL] = fireb;
#endif
}
}
}
}
#ifdef OGLR
//Go into array mode
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(cablurLine)
{
// -- BEGIN LINES -- //
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable( GL_LINE_SMOOTH );
glColorPointer(4, GL_FLOAT, 0, &ablurLineC[0]);
glVertexPointer(2, GL_FLOAT, 0, &ablurLineV[0]);
glDrawArrays(GL_LINES, 0, cablurLine);
//Clear some stuff we set
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_LINE_SMOOTH);
// -- END LINES -- //
}
if(cblurLine)
{
// -- BEGIN LINES -- //
glEnable( GL_LINE_SMOOTH );
glColorPointer(4, GL_FLOAT, 0, &blurLineC[0]);
glVertexPointer(2, GL_FLOAT, 0, &blurLineV[0]);
glDrawArrays(GL_LINES, 0, cblurLine);
//Clear some stuff we set
glDisable(GL_LINE_SMOOTH);
// -- END LINES -- //
}
if(cflat)
{
// -- BEGIN FLAT -- //
//Set point size (size of fire texture)
glPointSize(1.0f);
glColorPointer(4, GL_FLOAT, 0, &flatC[0]);
glVertexPointer(2, GL_INT, 0, &flatV[0]);
glDrawArrays(GL_POINTS, 0, cflat);
//Clear some stuff we set
// -- END FLAT -- //
}
if(cblob)
{
// -- BEGIN BLOB -- //
glEnable( GL_POINT_SMOOTH ); //Blobs!
glPointSize(2.5f);
glColorPointer(4, GL_FLOAT, 0, &blobC[0]);
glVertexPointer(2, GL_INT, 0, &blobV[0]);
glDrawArrays(GL_POINTS, 0, cblob);
//Clear some stuff we set
glDisable( GL_POINT_SMOOTH );
// -- END BLOB -- //
}
if(cglow || cblur)
{
// -- BEGIN GLOW -- //
//Start and prepare fire program
glEnable(GL_TEXTURE_2D);
glUseProgram(fireProg);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, glowAlpha);
glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0);
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
//Make sure we can use texture coords on points
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
//Set point size (size of fire texture)
glPointSize(11.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if(cglow)
{
glColorPointer(4, GL_FLOAT, 0, &glowC[0]);
glVertexPointer(2, GL_INT, 0, &glowV[0]);
glDrawArrays(GL_POINTS, 0, cglow);
}
glPointSize(7.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(cblur)
{
glBindTexture(GL_TEXTURE_2D, blurAlpha);
glColorPointer(4, GL_FLOAT, 0, &blurC[0]);
glVertexPointer(2, GL_INT, 0, &blurV[0]);
glDrawArrays(GL_POINTS, 0, cblur);
}
//Clear some stuff we set
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
// -- END GLOW -- //
}
if(cadd)
{
// -- BEGIN ADD -- //
//Set point size (size of fire texture)
glPointSize(1.0f);
glColorPointer(4, GL_FLOAT, 0, &addC[0]);
glVertexPointer(2, GL_INT, 0, &addV[0]);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDrawArrays(GL_POINTS, 0, cadd);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Clear some stuff we set
// -- END ADD -- //
}
if(cline)
{
// -- BEGIN LINES -- //
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable( GL_LINE_SMOOTH );
glColorPointer(4, GL_FLOAT, 0, &lineC[0]);
glVertexPointer(2, GL_FLOAT, 0, &lineV[0]);
glDrawArrays(GL_LINE_STRIP, 0, cline);
//Clear some stuff we set
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_LINE_SMOOTH);
// -- END LINES -- //
}
if(cfire || csmoke)
{
// -- BEGIN FIRE -- //
//Start and prepare fire program
glEnable(GL_TEXTURE_2D);
glUseProgram(fireProg);
//glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fireAlpha);
glUniform1i(glGetUniformLocation(fireProg, "fireAlpha"), 0);
//Make sure we can use texture coords on points
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
//Set point size (size of fire texture)
glPointSize(CELL*3);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if(cfire)
{
glColorPointer(4, GL_FLOAT, 0, &fireC[0]);
glVertexPointer(2, GL_INT, 0, &fireV[0]);
glDrawArrays(GL_POINTS, 0, cfire);
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(csmoke)
{
glColorPointer(4, GL_FLOAT, 0, &smokeC[0]);
glVertexPointer(2, GL_INT, 0, &smokeV[0]);
glDrawArrays(GL_POINTS, 0, csmoke);
}
//Clear some stuff we set
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
// -- END FIRE -- //
}
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
//Reset FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//Drawing the FBO onto the screen sounds like a cool idea now
glBlendFunc(origBlendSrc, origBlendDst);
#endif
}
#ifdef OGLR
void draw_parts_fbo()
{
glEnable( GL_TEXTURE_2D );
if(display_mode & DISPLAY_WARP)
{
float xres = XRES, yres = YRES;
glUseProgram(lensProg);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, partsFboTex);
glUniform1i(glGetUniformLocation(lensProg, "pTex"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, partsTFX);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, gravx);
glUniform1i(glGetUniformLocation(lensProg, "tfX"), 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, partsTFY);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, gravy);
glUniform1i(glGetUniformLocation(lensProg, "tfY"), 2);
glActiveTexture(GL_TEXTURE0);
glUniform1fv(glGetUniformLocation(lensProg, "xres"), 1, &xres);
glUniform1fv(glGetUniformLocation(lensProg, "yres"), 1, &yres);
}
else
{
glBindTexture(GL_TEXTURE_2D, partsFboTex);
glBlendFunc(GL_ONE, GL_ONE);
}
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2d(1, 0);
glVertex3f(XRES*sdl_scale, (YRES+MENUSIZE)*sdl_scale, 1.0);
glTexCoord2d(0, 0);
glVertex3f(0, (YRES+MENUSIZE)*sdl_scale, 1.0);
glTexCoord2d(0, 1);
glVertex3f(0, MENUSIZE*sdl_scale, 1.0);
glTexCoord2d(1, 1);
glVertex3f(XRES*sdl_scale, MENUSIZE*sdl_scale, 1.0);
glEnd();
if(display_mode & DISPLAY_WARP)
{
glUseProgram(0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glDisable( GL_TEXTURE_2D );
}
#endif
// draw the graphics that appear before update_particles is called
void render_before(pixel *part_vbuf)
{
#ifdef OGLR
if (display_mode & DISPLAY_PERS)//save background for persistent, then clear
{
clearScreen(0.01f);
memset(part_vbuf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE);
}
else //clear screen every frame
{
clearScreen(1.0f);
memset(part_vbuf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE);
if (display_mode & DISPLAY_AIR)//air only gets drawn in these modes
{
draw_air(part_vbuf);
}
}
#else
if (display_mode & DISPLAY_AIR)//air only gets drawn in these modes
{
draw_air(part_vbuf);
}
else if (display_mode & DISPLAY_PERS)//save background for persistent, then clear
{
memcpy(part_vbuf, pers_bg, (XRES+BARSIZE)*YRES*PIXELSIZE);
memset(part_vbuf+((XRES+BARSIZE)*YRES), 0, ((XRES+BARSIZE)*YRES*PIXELSIZE)-((XRES+BARSIZE)*YRES*PIXELSIZE));
}
else //clear screen every frame
{
memset(part_vbuf, 0, (XRES+BARSIZE)*YRES*PIXELSIZE);
}
#endif
if(ngrav_enable && drawgrav_enable)
draw_grav(part_vbuf);
draw_walls(part_vbuf);
}
int persist_counter = 0;
// draw the graphics that appear after update_particles is called
void render_after(pixel *part_vbuf, pixel *vid_buf)
{
render_parts(part_vbuf); //draw particles
draw_other(part_vbuf);
//if(su == WL_GRAV+100)
// draw_grav_zones(part_vbuf);
if (vid_buf && (display_mode & DISPLAY_PERS))
{
if (!persist_counter)
{
dim_copy_pers(pers_bg, vid_buf);
}
else
{
memcpy(pers_bg, vid_buf, (XRES+BARSIZE)*YRES*PIXELSIZE);
}
persist_counter = (persist_counter+1) % 3;
}
#ifndef OGLR
if (render_mode & FIREMODE)
render_fire(part_vbuf);
#endif
render_signs(part_vbuf);
#ifndef OGLR
if(vid_buf && ngrav_enable && (display_mode & DISPLAY_WARP))
render_gravlensing(part_vbuf, vid_buf);
#endif
}
void draw_walls(pixel *vid)
{
int x, y, i, j, cr, cg, cb, nx, ny, t;
unsigned char wt;
float lx, ly;
pixel pc;
pixel gc;
for (y=0; y=UI_WALLCOUNT)
continue;
pc = wtypes[wt].colour;
gc = wtypes[wt].eglow;
// standard wall patterns
if (wtypes[wt].drawstyle==1)
{
for (j=0; j>1)&1; i>1)&1; i 255) cr = 255;
fire_r[y][x] = cr;
cg = fire_g[y][x] + PIXG(pc);
if (cg > 255) cg = 255;
fire_g[y][x] = cg;
cb = fire_b[y][x] + PIXB(pc);
if (cb > 255) cb = 255;
fire_b[y][x] = cb;
}
}
// draw streamlines
for (y=0; y=XRES || ny<0 || ny>=YRES)
break;
addpixel(vid, nx, ny, 255, 255, 255, 64);
i = nx/CELL;
j = ny/CELL;
lx += vx[j][i]*0.125f;
ly += vy[j][i]*0.125f;
if (bmap[j][i]==WL_STREAM && i!=x && j!=y)
break;
}
drawtext(vid, x*CELL, y*CELL-2, "\x8D", 255, 255, 255, 128);
}
}
void create_decorations(int x, int y, int rx, int ry, int r, int g, int b, int click, int tool)
{
int i,j,rp;
if (rx==0 && ry==0)
{
create_decoration(x,y,r,g,b,click,tool);
return;
}
for (j=-ry; j<=ry; j++)
for (i=-rx; i<=rx; i++)
if(y+j>=0 && x+i>=0 && x+i>8].dcolour = 0;
else
parts[rp>>8].dcolour = ((255<<24)|(r<<16)|(g<<8)|b);
}
else if (tool == DECO_LIGHTEN)
{//maybe get a better lighten/darken?
if (parts[rp>>8].dcolour == 0)
return;
tr = (parts[rp>>8].dcolour>>16)&0xFF;
tg = (parts[rp>>8].dcolour>>8)&0xFF;
tb = (parts[rp>>8].dcolour)&0xFF;
parts[rp>>8].dcolour = ((parts[rp>>8].dcolour&0xFF000000)|(clamp_flt(tr+(255-tr)*0.02+1, 0,255)<<16)|(clamp_flt(tg+(255-tg)*0.02+1, 0,255)<<8)|clamp_flt(tb+(255-tb)*0.02+1, 0,255));
}
else if (tool == DECO_DARKEN)
{
if (parts[rp>>8].dcolour == 0)
return;
tr = (parts[rp>>8].dcolour>>16)&0xFF;
tg = (parts[rp>>8].dcolour>>8)&0xFF;
tb = (parts[rp>>8].dcolour)&0xFF;
parts[rp>>8].dcolour = ((parts[rp>>8].dcolour&0xFF000000)|(clamp_flt(tr-(tr)*0.02, 0,255)<<16)|(clamp_flt(tg-(tg)*0.02, 0,255)<<8)|clamp_flt(tb-(tb)*0.02, 0,255));
}
else if (tool == DECO_SMUDGE)
{
int rx, ry, num = 0, ta = 0;
for (rx=-2; rx<3; rx++)
for (ry=-2; ry<3; ry++)
{
if ((pmap[y+ry][x+rx]&0xFF) && parts[pmap[y+ry][x+rx]>>8].dcolour)
{
num++;
ta += (parts[pmap[y+ry][x+rx]>>8].dcolour>>24)&0xFF;
tr += (parts[pmap[y+ry][x+rx]>>8].dcolour>>16)&0xFF;
tg += (parts[pmap[y+ry][x+rx]>>8].dcolour>>8)&0xFF;
tb += (parts[pmap[y+ry][x+rx]>>8].dcolour)&0xFF;
}
}
if (num == 0)
return;
ta = fminf(255,(int)((float)ta/num+.5));
tr = fminf(255,(int)((float)tr/num+.5));
tg = fminf(255,(int)((float)tg/num+.5));
tb = fminf(255,(int)((float)tb/num+.5));
if (!parts[rp>>8].dcolour)
ta = fmaxf(0,ta-3);
parts[rp>>8].dcolour = ((ta<<24)|(tr<<16)|(tg<<8)|tb);
}
}
void line_decorations(int x1, int y1, int x2, int y2, int rx, int ry, int r, int g, int b, int click, int tool)
{
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
float e, de;
if (cp)
{
y = x1;
x1 = y1;
y1 = y;
y = x2;
x2 = y2;
y2 = y;
}
if (x1 > x2)
{
y = x1;
x1 = x2;
x2 = y;
y = y1;
y1 = y2;
y2 = y;
}
dx = x2 - x1;
dy = abs(y2 - y1);
e = 0.0f;
if (dx)
de = dy/(float)dx;
else
de = 0.0f;
y = y1;
sy = (y1= 0.5f)
{
y += sy;
if (!(rx+ry))
{
if (cp)
create_decorations(y, x, rx, ry, r, g, b, click, tool);
else
create_decorations(x, y, rx, ry, r, g, b, click, tool);
}
e -= 1.0f;
}
}
}
void box_decorations(int x1, int y1, int x2, int y2, int r, int g, int b, int click, int tool)
{
int i, j;
if (x1>x2)
{
i = x2;
x2 = x1;
x1 = i;
}
if (y1>y2)
{
j = y2;
y2 = y1;
y1 = j;
}
for (j=y1; j<=y2; j++)
for (i=x1; i<=x2; i++)
create_decorations(i, j, 0, 0, r, g, b, click, tool);
}
//draws the photon colors in the HUD
void draw_wavelengths(pixel *vid, int x, int y, int h, int wl)
{
int i,cr,cg,cb,j;
int tmp;
fillrect(vid,x-1,y-1,30+1,h+1,64,64,64,255); // coords -1 size +1 to work around bug in fillrect - TODO: fix fillrect
for (i=0; i<30; i++)
{
if ((wl>>i)&1)
{
// Need a spread of wavelengths to get a smooth spectrum, 5 bits seems to work reasonably well
if (i>2) tmp = 0x1F << (i-2);
else tmp = 0x1F >> (2-i);
cg = 0;
cb = 0;
cr = 0;
for (j=0; j<12; j++) {
cr += (tmp >> (j+18)) & 1;
cb += (tmp >> j) & 1;
}
for (j=0; j<13; j++)
cg += (tmp >> (j+9)) & 1;
tmp = 624/(cr+cg+cb+1);
cr *= tmp;
cg *= tmp;
cb *= tmp;
for (j=0; j255?255:cr,cg>255?255:cg,cb>255?255:cb,255);
}
}
}
void render_signs(pixel *vid_buf)
{
int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq;
for (i=0; i=0 && signs[i].x=0 && signs[i].y=0 && signs[i].x=0 && signs[i].y>8].temp-273.15); //...temperature
else
sprintf(buff, "Temp: 0.00"); //...temperature
drawtext(vid_buf, x+3, y+3, buff, 255, 255, 255, 255);
}
if (sregexp(signs[i].text, "^{c:[0-9]*|.*}$")==0)
{
int sldr, startm;
memset(buff, 0, sizeof(buff));
for (sldr=3; signs[i].text[sldr-1] != '|'; sldr++)
startm = sldr + 1;
sldr = startm;
while (signs[i].text[sldr] != '}')
{
buff[sldr - startm] = signs[i].text[sldr];
sldr++;
}
drawtext(vid_buf, x+3, y+3, buff, 0, 191, 255, 255);
}
//Usual text
if (strcmp(signs[i].text, "{p}") && strcmp(signs[i].text, "{t}") && sregexp(signs[i].text, "^{c:[0-9]*|.*}$"))
drawtext(vid_buf, x+3, y+3, signs[i].text, 255, 255, 255, 255);
x = signs[i].x;
y = signs[i].y;
dx = 1 - signs[i].ju;
dy = (signs[i].y > 18) ? -1 : 1;
for (j=0; j<4; j++)
{
drawpixel(vid_buf, x, y, 192, 192, 192, 255);
x+=dx;
y+=dy;
}
if (MSIGN==i)
{
bq = b;
mouse_get_state(&mx, &my);
mouse_coords_window_to_sim(&mx, &my, mx, my);
signs[i].x = mx;
signs[i].y = my;
}
}
}
void render_gravlensing(pixel *src, pixel * dst)
{
int nx, ny, rx, ry, gx, gy, bx, by, co;
int r, g, b;
pixel t;
for(nx = 0; nx < XRES; nx++)
{
for(ny = 0; ny < YRES; ny++)
{
co = (ny/CELL)*(XRES/CELL)+(nx/CELL);
rx = (int)(nx-gravx[co]*0.75f+0.5f);
ry = (int)(ny-gravy[co]*0.75f+0.5f);
gx = (int)(nx-gravx[co]*0.875f+0.5f);
gy = (int)(ny-gravy[co]*0.875f+0.5f);
bx = (int)(nx-gravx[co]+0.5f);
by = (int)(ny-gravy[co]+0.5f);
if(rx > 0 && rx < XRES && ry > 0 && ry < YRES && gx > 0 && gx < XRES && gy > 0 && gy < YRES && bx > 0 && bx < XRES && by > 0 && by < YRES)
{
t = dst[ny*(XRES+BARSIZE)+nx];
r = PIXR(src[ry*(XRES+BARSIZE)+rx]) + PIXR(t);
g = PIXG(src[gy*(XRES+BARSIZE)+gx]) + PIXG(t);
b = PIXB(src[by*(XRES+BARSIZE)+bx]) + PIXB(t);
if (r>255)
r = 255;
if (g>255)
g = 255;
if (b>255)
b = 255;
dst[ny*(XRES+BARSIZE)+nx] = PIXRGB(r,g,b);
// addpixel(dst, nx, ny, PIXR(src[ry*(XRES+BARSIZE)+rx]), PIXG(src[gy*(XRES+BARSIZE)+gx]), PIXB(src[by*(XRES+BARSIZE)+bx]), 255);
}
/*rx = nx+(gravxf[(ny*XRES)+nx]*0.5f);
ry = ny+(gravyf[(ny*XRES)+nx]*0.5f);
gx = nx+(gravxf[(ny*XRES)+nx]*0.75f);
gy = ny+(gravyf[(ny*XRES)+nx]*0.75f);
bx = nx+(gravxf[(ny*XRES)+nx]);
by = ny+(gravyf[(ny*XRES)+nx]);
if(rx > 0 && rx < XRES && ry > 0 && ry < YRES && gravp[ny/CELL][nx/CELL]*0.5f > -8.0f)
addpixel(dst, rx, ry, PIXR(src[ry*(XRES+BARSIZE)+rx]), 0, 0, 255);
if(gx > 0 && gx < XRES && gy > 0 && gy < YRES && gravp[ny/CELL][nx/CELL]*0.75f > -8.0f)
addpixel(dst, gx, gy, 0, PIXG(src[ry*(XRES+BARSIZE)+rx]), 0, 255);
if(bx > 0 && bx < XRES && by > 0 && by < YRES && gravp[ny/CELL][nx/CELL] > -8.0f)
addpixel(dst, bx, by, 0, 0, PIXB(src[ry*(XRES+BARSIZE)+rx]), 255);*/
}
}
}
void render_fire(pixel *vid)
{
int i,j,x,y,r,g,b,nx,ny;
for (j=0; j=0 && j+y>=0 && i+x4 ? r-4 : 0;
fire_g[j][i] = g>4 ? g-4 : 0;
fire_b[j][i] = b>4 ? b-4 : 0;
}
}
void prepare_alpha(int size, float intensity)
{
//TODO: implement size
int x,y,i,j,c;
float multiplier = 255.0f*intensity;
float temp[CELL*3][CELL*3];
float fire_alphaf[CELL*3][CELL*3];
float glow_alphaf[11][11];
float blur_alphaf[7][7];
memset(temp, 0, sizeof(temp));
for (x=0; x| 7)
continue;
glow_alphaf[c+x][c-y] += 0.02f;
glow_alphaf[c-x][c+y] += 0.02f;
glow_alphaf[c+x][c+y] += 0.02f;
glow_alphaf[c-x][c-y] += 0.02f;
}
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glowAlpha);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 11, 11, GL_ALPHA, GL_FLOAT, glow_alphaf);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
c = 3;
for (x=-3; x<4; x++)
{
for (y=-3; y<4; y++)
{
if (abs(x)+abs(y) <2 && !(abs(x)==2||abs(y)==2))
blur_alphaf[c+x][c-y] = 0.11f;
if (abs(x)+abs(y) <=3 && abs(x)+abs(y))
blur_alphaf[c+x][c-y] = 0.08f;
if (abs(x)+abs(y) == 2)
blur_alphaf[c+x][c-y] = 0.04f;
}
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, blurAlpha);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 7, 7, GL_ALPHA, GL_FLOAT, blur_alphaf);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
#endif
}
pixel *render_packed_rgb(void *image, int width, int height, int cmp_size)
{
unsigned char *tmp;
pixel *res;
int i;
tmp = malloc(width*height*3);
if (!tmp)
return NULL;
res = malloc(width*height*PIXELSIZE);
if (!res)
{
free(tmp);
return NULL;
}
i = width*height*3;
if (BZ2_bzBuffToBuffDecompress((char *)tmp, (unsigned *)&i, (char *)image, cmp_size, 0, 0))
{
free(res);
free(tmp);
return NULL;
}
for (i=0; i0)
r--;
if (g>0)
g--;
if (b>0)
b--;
dst[i] = PIXRGB(r,g,b);
}
}
void dim_copy_pers(pixel *dst, pixel *src) //for persistent view, reduces rgb slowly
{
int i,r,g,b;
for (i=0; i<(XRES+BARSIZE)*YRES; i++)
{
r = PIXR(src[i]);
g = PIXG(src[i]);
b = PIXB(src[i]);
if (r>0)
r--;
if (g>0)
g--;
if (b>0)
b--;
dst[i] = PIXRGB(r,g,b);
}
}
void render_zoom(pixel *img) //draws the zoom box
{
#ifdef OGLR
int origBlendSrc, origBlendDst;
float zcx1, zcx0, zcy1, zcy0, yfactor, xfactor, i; //X-Factor is shit, btw
xfactor = 1.0f/(float)XRES;
yfactor = 1.0f/(float)YRES;
zcx0 = (zoom_x)*xfactor;
zcx1 = (zoom_x+ZSIZE)*xfactor;
zcy0 = (zoom_y)*yfactor;
zcy1 = ((zoom_y+ZSIZE))*yfactor;
glGetIntegerv(GL_BLEND_SRC, &origBlendSrc);
glGetIntegerv(GL_BLEND_DST, &origBlendDst);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable( GL_TEXTURE_2D );
//glReadBuffer(GL_AUX0);
glBindTexture(GL_TEXTURE_2D, partsFboTex);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2d(zcx1, zcy1);
glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0);
glTexCoord2d(zcx0, zcy1);
glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0);
glTexCoord2d(zcx0, zcy0);
glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0);
glTexCoord2d(zcx1, zcy0);
glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable( GL_TEXTURE_2D );
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLineWidth(sdl_scale);
glEnable(GL_LINE_SMOOTH);
glBegin(GL_LINES);
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
for(i = 0; i < ZSIZE; i++)
{
glVertex2f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale);
glVertex2f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale);
glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale);
glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale);
}
glEnd();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_LINE_STRIP);
glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0);
glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0);
glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0);
glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0);
glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0);
glEnd();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_LINE_SMOOTH);
if(zoom_en)
{
glEnable(GL_COLOR_LOGIC_OP);
//glEnable(GL_LINE_SMOOTH);
glLogicOp(GL_XOR);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_LINE_STRIP);
glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0);
glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0);
glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0);
glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0);
glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0);
glEnd();
glDisable(GL_COLOR_LOGIC_OP);
}
glLineWidth(1);
glBlendFunc(origBlendSrc, origBlendDst);
#else
int x, y, i, j;
pixel pix;
drawrect(img, zoom_wx-2, zoom_wy-2, ZSIZE*ZFACTOR+2, ZSIZE*ZFACTOR+2, 192, 192, 192, 255);
drawrect(img, zoom_wx-1, zoom_wy-1, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR, 0, 0, 0, 255);
clearrect(img, zoom_wx, zoom_wy, ZSIZE*ZFACTOR, ZSIZE*ZFACTOR);
for (j=0; jPT_NUM)
return 2;
if (c[5]!=CELL || c[6]!=XRES/CELL || c[7]!=YRES/CELL)
return 3;
i = XRES*YRES;
d = malloc(i);
if (!d)
return 1;
if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+8), size-8, 0, 0))
return 1;
size = i;
}
else
d = c;
if (size < XRES*YRES)
{
if (bzip2)
free(d);
return 1;
}
sy = 0;
for (y=0; y+scl<=YRES; y+=scl)
{
sx = 0;
for (x=0; x+scl<=XRES; x+=scl)
{
a = 0;
r = g = b = 0;
for (j=0; j=PT_NUM)
goto corrupt;
r += PIXR(ptypes[t].pcolors);
g += PIXG(ptypes[t].pcolors);
b += PIXB(ptypes[t].pcolors);
a ++;
}
}
if (a)
{
a = 256/a;
r = (r*a)>>8;
g = (g*a)>>8;
b = (b*a)>>8;
}
drawpixel(vid_buf, px+sx, py+sy, r, g, b, 255);
sx++;
}
sy++;
}
if (bzip2)
free(d);
return 0;
corrupt:
if (bzip2)
free(d);
return 1;
}
//draws the cursor
void render_cursor(pixel *vid, int x, int y, int t, int rx, int ry)
{
#ifdef OGLR
int i;
if (t YRES)
t1 = YRES;
if(t1+t2 > YRES)
t2 = YRES-t1;
if(t1>0)
draw_line(vid, x, YRES, x, YRES-t1, 0, 255, 120, XRES+BARSIZE);
if(t2>0)
draw_line(vid, x, YRES-t1, x, YRES-(t1+t2), 255, 120, 0, XRES+BARSIZE);
i++;
x++;
i %= DEBUG_PERF_FRAMECOUNT;
}
if(debug_flags & DEBUG_PERFORMANCE_CALC)
t1 = abs(partiavg / x);
else
t1 = 0;
if(debug_flags & DEBUG_PERFORMANCE_FRAME)
t2 = abs(frameavg / x);
else
t2 = 0;
if(t1 > YRES)
t1 = YRES;
if(t1+t2 > YRES)
t2 = YRES-t1;
if(t1>0)
fillrect(vid, x, YRES-t1-1, 5, t1+2, 0, 255, 0, 255);
if(t2>0)
fillrect(vid, x, (YRES-t1)-t2-1, 5, t2+1, 255, 0, 0, 255);
}
if(debug_flags & DEBUG_DRAWTOOL)
{
if(lm == 1) //Line tool
{
blend_line(vid, 0, line_y, XRES, line_y, 255, 255, 255, 120);
blend_line(vid, line_x, 0, line_x, YRES, 255, 255, 255, 120);
blend_line(vid, 0, ly, XRES, ly, 255, 255, 255, 120);
blend_line(vid, lx, 0, lx, YRES, 255, 255, 255, 120);
sprintf(infobuf, "%d x %d", lx, ly);
drawtext_outline(vid, lx+(lx>line_x?3:-textwidth(infobuf)-3), ly+(lyline_y?-10:3), infobuf, 255, 255, 255, 200, 0, 0, 0, 120);
sprintf(infobuf, "%d", abs(line_x-lx));
drawtext_outline(vid, (line_x+lx)/2-textwidth(infobuf)/2, line_y+(ly>line_y?-10:3), infobuf, 255, 255, 255, 200, 0, 0, 0, 120);
sprintf(infobuf, "%d", abs(line_y-ly));
drawtext_outline(vid, line_x+(lx=XRES){
y++;
x = 0;
}
}
draw_line(vid, 0, lpy, XRES, lpy, 0, 255, 120, XRES+BARSIZE);
draw_line(vid, lpx, 0, lpx, YRES, 0, 255, 120, XRES+BARSIZE);
drawpixel(vid, lpx, lpy, 255, 50, 50, 220);
drawpixel(vid, lpx+1, lpy, 255, 50, 50, 120);
drawpixel(vid, lpx-1, lpy, 255, 50, 50, 120);
drawpixel(vid, lpx, lpy+1, 255, 50, 50, 120);
drawpixel(vid, lpx, lpy-1, 255, 50, 50, 120);
fillrect(vid, 7, YRES-26, textwidth(infobuf)+5, 14, 0, 0, 0, 180);
drawtext(vid, 10, YRES-22, infobuf, 255, 255, 255, 255);
}
}
| | | | |