diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-08 17:39:03 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-01-08 17:39:03 (GMT) |
| commit | b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778 (patch) | |
| tree | 7d72e0509f4d2643d3be837a337d088ca5949c73 /src/Renderer.cpp | |
| download | powder-b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778.zip powder-b0ea52690ba56a0d0602ad8674b7e5ab2ba3e778.tar.gz | |
Initial
Diffstat (limited to 'src/Renderer.cpp')
| -rw-r--r-- | src/Renderer.cpp | 1692 |
1 files changed, 1692 insertions, 0 deletions
diff --git a/src/Renderer.cpp b/src/Renderer.cpp new file mode 100644 index 0000000..c1bbf3c --- /dev/null +++ b/src/Renderer.cpp @@ -0,0 +1,1692 @@ +/* + * Renderer.cpp + * + * Created on: Jan 7, 2012 + * Author: Simon + */ + +#include <math.h> +#include "Config.h" +#include "Renderer.h" +#include "Graphics.h" +#include "Elements.h" +#include "ElementFunctions.h" +#include "ElementGraphics.h" +#include "Air.h" +extern "C" +{ +#include "hmap.h" +} + +void Renderer::draw_walls() +{ + int x, y, i, j, cr, cg, cb; + unsigned char wt; + pixel pc; + pixel gc; + unsigned char (*bmap)[XRES/CELL] = sim->bmap; + unsigned char (*emap)[XRES/CELL] = sim->emap; + wall_type *wtypes = sim->wtypes; + pixel * vid = g->vid; + + for (y=0; y<YRES/CELL; y++) + for (x=0; x<XRES/CELL; x++) + if (bmap[y][x]) + { + wt = bmap[y][x]-UI_ACTUALSTART; + if (wt<0 || wt>=UI_WALLCOUNT) + continue; + pc = wtypes[wt].colour; + gc = wtypes[wt].eglow; + + // standard wall patterns + if (wtypes[wt].drawstyle==1) + { + for (j=0; j<CELL; j+=2) + for (i=(j>>1)&1; i<CELL; i+=2) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + } + else if (wtypes[wt].drawstyle==2) + { + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + } + else if (wtypes[wt].drawstyle==3) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + } + else if (wtypes[wt].drawstyle==4) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if(i == j) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + else if (i == j+1 || (i == 0 && j == CELL-1)) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = gc; + else + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x202020); + } + + // special rendering for some walls + if (bmap[y][x]==WL_EWALL) + { + if (emap[y][x]) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if (i&j&1) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + } + else + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if (!(i&j&1)) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + } + } + else if (bmap[y][x]==WL_WALLELEC) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + { + if (!((y*CELL+j)%2) && !((x*CELL+i)%2)) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = pc; + else + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x808080); + } + } + else if (bmap[y][x]==WL_EHOLE) + { + if (emap[y][x]) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x242424); + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x000000); + } + else + { + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x242424); + } + } + if (render_mode & PMODE_BLOB) + { + // when in blob view, draw some blobs... + if (wtypes[wt].drawstyle==1) + { + for (j=0; j<CELL; j+=2) + for (i=(j>>1)&1; i<CELL; i+=2) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + } + else if (wtypes[wt].drawstyle==2) + { + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + } + else if (wtypes[wt].drawstyle==3) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + } + else if (wtypes[wt].drawstyle==4) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if(i == j) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + else if (i == j+1 || (i == 0 && j == CELL-1)) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(gc), PIXG(gc), PIXB(gc)); + else + g->drawblob((x*CELL+i), (y*CELL+j), 0x20, 0x20, 0x20); + } + if (bmap[y][x]==WL_EWALL) + { + if (emap[y][x]) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if (i&j&1) + g->drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); + } + else + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + if (!(i&j&1)) + g->drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); + } + } + else if (bmap[y][x]==WL_WALLELEC) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + { + if (!((y*CELL+j)%2) && !((x*CELL+i)%2)) + g->drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + else + g->drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); + } + } + else if (bmap[y][x]==WL_EHOLE) + { + if (emap[y][x]) + { + for (j=0; j<CELL; j++) + for (i=0; i<CELL; i++) + g->drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + vid[(y*CELL+j)*(XRES+BARSIZE)+(x*CELL+i)] = PIXPACK(0x000000); + } + else + { + for (j=0; j<CELL; j+=2) + for (i=0; i<CELL; i+=2) + g->drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); + } + } + } + if (wtypes[wt].eglow && emap[y][x]) + { + // glow if electrified + pc = wtypes[wt].eglow; + cr = fire_r[y][x] + PIXR(pc); + if (cr > 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; + + } + } +} + +void Renderer::get_sign_pos(int i, int *x0, int *y0, int *w, int *h) +{ + sign *signs = sim->signs; + //Changing width if sign have special content + if (strcmp(signs[i].text, "{p}")==0) + *w = Graphics::textwidth("Pressure: -000.00"); + + if (strcmp(signs[i].text, "{t}")==0) + *w = Graphics::textwidth("Temp: 0000.00"); + + if (sregexp(signs[i].text, "^{c:[0-9]*|.*}$")==0) + { + int sldr, startm; + char buff[256]; + 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++; + } + *w = Graphics::textwidth(buff) + 5; + } + + //Ususal width + if (strcmp(signs[i].text, "{p}") && strcmp(signs[i].text, "{t}") && sregexp(signs[i].text, "^{c:[0-9]*|.*}$")) + *w = Graphics::textwidth(signs[i].text) + 5; + *h = 14; + *x0 = (signs[i].ju == 2) ? signs[i].x - *w : + (signs[i].ju == 1) ? signs[i].x - *w/2 : signs[i].x; + *y0 = (signs[i].y > 18) ? signs[i].y - 18 : signs[i].y + 4; +} + +void Renderer::render_signs() +{ + int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq; + sign *signs = sim->signs; + for (i=0; i<MAXSIGNS; i++) + if (signs[i].text[0]) + { + char buff[256]; //Buffer + get_sign_pos(i, &x, &y, &w, &h); + g->clearrect(x, y, w, h); + g->drawrect(x, y, w, h, 192, 192, 192, 255); + + //Displaying special information + if (strcmp(signs[i].text, "{p}")==0) + { + sprintf(buff, "Pressure: %3.2f", sim->pv[signs[i].y/CELL][signs[i].x/CELL]); //...pressure + g->drawtext(x+3, y+3, buff, 255, 255, 255, 255); + } + if (strcmp(signs[i].text, "{t}")==0) + { + if (sim->pmap[signs[i].y][signs[i].x]) + sprintf(buff, "Temp: %4.2f", sim->parts[sim->pmap[signs[i].y][signs[i].x]>>8].temp-273.15); //...tempirature + else + sprintf(buff, "Temp: 0.00"); //...tempirature + g->drawtext(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++; + } + g->drawtext(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]*|.*}$")) + g->drawtext(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++) + { + g->drawpixel(x, y, 192, 192, 192, 255); + x+=dx; + y+=dy; + } + /*if (MSIGN==i) + { + bq = b; + b = SDL_GetMouseState(&mx, &my); + mx /= sdl_scale; + my /= sdl_scale; + signs[i].x = mx; + signs[i].y = my; + }*/ + } +} + +void Renderer::render_gravlensing() +{ + int nx, ny, rx, ry, gx, gy, bx, by, co; + int r, g, b; + pixel t; + pixel *src = this->g->vid; + pixel *dst = this->g->vid; + for(nx = 0; nx < XRES; nx++) + { + for(ny = 0; ny < YRES; ny++) + { + co = (ny/CELL)*(XRES/CELL)+(nx/CELL); + rx = (int)(nx-sim->gravx[co]*0.75f+0.5f); + ry = (int)(ny-sim->gravy[co]*0.75f+0.5f); + gx = (int)(nx-sim->gravx[co]*0.875f+0.5f); + gy = (int)(ny-sim->gravy[co]*0.875f+0.5f); + bx = (int)(nx-sim->gravx[co]+0.5f); + by = (int)(ny-sim->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 Renderer::render_fire() +{ + int i,j,x,y,r,g,b,nx,ny; + for (j=0; j<YRES/CELL; j++) + for (i=0; i<XRES/CELL; i++) + { + r = fire_r[j][i]; + g = fire_g[j][i]; + b = fire_b[j][i]; + if (r || g || b) + for (y=-CELL+1; y<2*CELL; y++) + for (x=-CELL+1; x<2*CELL; x++) + this->g->addpixel(i*CELL+x, j*CELL+y, r, g, b, fire_alpha[y+CELL][x+CELL]); + r *= 8; + g *= 8; + b *= 8; + for (y=-1; y<2; y++) + for (x=-1; x<2; x++) + if ((x || y) && i+x>=0 && j+y>=0 && i+x<XRES/CELL && j+y<YRES/CELL) + { + r += fire_r[j+y][i+x]; + g += fire_g[j+y][i+x]; + b += fire_b[j+y][i+x]; + } + r /= 16; + g /= 16; + b /= 16; + fire_r[j][i] = r>4 ? r-4 : 0; + fire_g[j][i] = g>4 ? g-4 : 0; + fire_b[j][i] = b>4 ? b-4 : 0; + } +} + +void Renderer::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<CELL; x++) + for (y=0; y<CELL; y++) + for (i=-CELL; i<CELL; i++) + for (j=-CELL; j<CELL; j++) + temp[y+CELL+j][x+CELL+i] += expf(-0.1f*(i*i+j*j)); + for (x=0; x<CELL*3; x++) + for (y=0; y<CELL*3; y++) + fire_alpha[y][x] = (int)(multiplier*temp[y][x]/(CELL*CELL)); + +#ifdef OGLR + for (x=0; x<CELL*3; x++) + for (y=0; y<CELL*3; y++) + { + fire_alphaf[y][x] = intensity*temp[y][x]/((float)(CELL*CELL)); + } + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fireAlpha); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CELL*3, CELL*3, GL_ALPHA, GL_FLOAT, fire_alphaf); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + memset(glow_alphaf, 0, sizeof(glow_alphaf)); + + c = 5; + + glow_alphaf[c][c-1] = 0.4f; + glow_alphaf[c][c+1] = 0.4f; + glow_alphaf[c-1][c] = 0.4f; + glow_alphaf[c+1][c] = 0.4f; + for (x = 1; x < 6; x++) { + glow_alphaf[c][c-x] += 0.02f; + glow_alphaf[c][c+x] += 0.02f; + glow_alphaf[c-x][c] += 0.02f; + glow_alphaf[c+x][c] += 0.02f; + for (y = 1; y < 6; y++) { + if(x + y > 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 +} + +void Renderer::render_parts() +{ + int deca, decr, decg, decb, cola, colr, colg, colb, firea, firer, fireg, fireb, pixel_mode, q, i, t, nx, ny, x, y, caddress; + int orbd[4] = {0, 0, 0, 0}, orbl[4] = {0, 0, 0, 0}; + float gradv, flicker, fnx, fny; + Particle * parts = sim->parts; + part_transition *ptransitions = sim->ptransitions; + part_type *ptypes = sim->ptypes; +#ifdef OGLR + int cfireV = 0, cfireC = 0, cfire = 0; + int csmokeV = 0, csmokeC = 0, csmoke = 0; + int cblobV = 0, cblobC = 0, cblob = 0; + int cblurV = 0, cblurC = 0, cblur = 0; + int cglowV = 0, cglowC = 0, cglow = 0; + int cflatV = 0, cflatC = 0, cflat = 0; + int caddV = 0, caddC = 0, cadd = 0; + int clineV = 0, clineC = 0, cline = 0; + GLuint origBlendSrc, origBlendDst; + + glGetIntegerv(GL_BLEND_SRC, &origBlendSrc); + glGetIntegerv(GL_BLEND_DST, &origBlendDst); + //Render to the particle FBO + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); +#else + /*if (GRID_MODE)//draws the grid + { + for (ny=0; ny<YRES; ny++) + for (nx=0; nx<XRES; nx++) + { + if (ny%(4*GRID_MODE)==0) + blendpixel(nx, ny, 100, 100, 100, 80); + if (nx%(4*GRID_MODE)==0) + blendpixel(nx, ny, 100, 100, 100, 80); + } + }*/ +#endif + for(i = 0; i<=sim->parts_lastActiveIndex; i++) { + if (sim->parts[i].type) { + t = sim->parts[i].type; + + nx = (int)(sim->parts[i].x+0.5f); + ny = (int)(sim->parts[i].y+0.5f); + fnx = sim->parts[i].x; + fny = sim->parts[i].y; + + if((sim->photons[ny][nx]&0xFF) && !(ptypes[t].properties & TYPE_ENERGY)) + continue; + + //Defaults + pixel_mode = 0 | PMODE_FLAT; + cola = 255; + colr = PIXR(ptypes[t].pcolors); + colg = PIXG(ptypes[t].pcolors); + colb = PIXB(ptypes[t].pcolors); + firea = 0; + + deca = (sim->parts[i].dcolour>>24)&0xFF; + decr = (sim->parts[i].dcolour>>16)&0xFF; + decg = (sim->parts[i].dcolour>>8)&0xFF; + decb = (sim->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 (ptypes[t].graphics_func) + { + if ((*(ptypes[t].graphics_func))(this, &(sim->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(this, &(sim->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) && sim->parts[i].temp>(ptransitions[t].thv-800.0f)) + { + gradv = 3.1415/(2*ptransitions[t].thv-(ptransitions[t].thv-800.0f)); + caddress = (sim->parts[i].temp>ptransitions[t].thv)?ptransitions[t].thv-(ptransitions[t].thv-800.0f):sim->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_FLAT; + 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)(sim->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 (!(sim->parts[i].life<5)) + q = sqrt(sim->parts[i].life); + else + q = sim->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_GRAD) + { + float frequency = 0.05; + int q = sim->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; + } + + //Apply decoration colour + if(!colour_mode) + { + 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; + } + } + + #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; + #endif + + //Pixel rendering + if(pixel_mode & PSPEC_STICKMAN) + { + char buff[20]; //Buffer for HP + int s; + int legr, legg, legb; + playerst *cplayer; + if(t==PT_STKM) + cplayer = &sim->player; + else if(t==PT_STKM2) + cplayer = &sim->player2; + else if(t==PT_FIGH) + cplayer = &sim->fighters[(unsigned char)sim->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", sim->parts[i].life); //Show HP + g->drawtext(mousex-8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), mousey-12, buff, 255, 255, 255, 255); + }*/ + + if (colour_mode!=COLOUR_HEAT) + { + if (cplayer->elem<PT_NUM) + { + colr = PIXR(ptypes[cplayer->elem].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) + { + g->draw_line(nx, ny+2, nx+2, ny, colr, colg, colb, s); + g->draw_line(nx+2, ny, nx, ny-2, colr, colg, colb, s); + g->draw_line(nx, ny-2, nx-2, ny, colr, colg, colb, s); + g->draw_line(nx-2, ny, nx, ny+2, colr, colg, colb, s); + } + else + { + g->draw_line(nx-2, ny+2, nx+2, ny+2, colr, colg, colb, s); + g->draw_line(nx-2, ny-2, nx+2, ny-2, colr, colg, colb, s); + g->draw_line(nx-2, ny-2, nx-2, ny+2, colr, colg, colb, s); + g->draw_line(nx+2, ny-2, nx+2, ny+2, colr, colg, colb, s); + } + //legs + g->draw_line(nx, ny+3, cplayer->legs[0], cplayer->legs[1], legr, legg, legb, s); + g->draw_line(cplayer->legs[0], cplayer->legs[1], cplayer->legs[4], cplayer->legs[5], legr, legg, legb, s); + g->draw_line(nx, ny+3, cplayer->legs[8], cplayer->legs[9], legr, legg, legb, s); + g->draw_line(cplayer->legs[8], cplayer->legs[9], cplayer->legs[12], cplayer->legs[13], legr, legg, legb, s); +#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 + g->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 + g->blendpixel(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 + g->addpixel(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 + g->vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(colr,colg,colb); + + g->blendpixel(nx+1, ny, colr, colg, colb, 223); + g->blendpixel(nx-1, ny, colr, colg, colb, 223); + g->blendpixel(nx, ny+1, colr, colg, colb, 223); + g->blendpixel(nx, ny-1, colr, colg, colb, 223); + + g->blendpixel(nx+1, ny-1, colr, colg, colb, 112); + g->blendpixel(nx-1, ny-1, colr, colg, colb, 112); + g->blendpixel(nx+1, ny+1, colr, colg, colb, 112); + g->blendpixel(nx-1, ny+1, colr, colg, colb, 112); +#endif + } + if(pixel_mode & PMODE_GLOW) + { +#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 + g->addpixel(nx, ny, colr, colg, colb, 192); + g->addpixel(nx+1, ny, colr, colg, colb, 96); + g->addpixel(nx-1, ny, colr, colg, colb, 96); + g->addpixel(nx, ny+1, colr, colg, colb, 96); + g->addpixel(nx, ny-1, colr, colg, colb, 96); + + for (x = 1; x < 6; x++) { + g->addpixel(nx, ny-x, colr, colg, colb, 5); + g->addpixel(nx, ny+x, colr, colg, colb, 5); + g->addpixel(nx-x, ny, colr, colg, colb, 5); + g->addpixel(nx+x, ny, colr, colg, colb, 5); + for (y = 1; y < 6; y++) { + if(x + y > 7) + continue; + g->addpixel(nx+x, ny-y, colr, colg, colb, 5); + g->addpixel(nx-x, ny+y, colr, colg, colb, 5); + g->addpixel(nx+x, ny+y, colr, colg, colb, 5); + g->addpixel(nx-x, ny-y, colr, colg, colb, 5); + } + } +#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)) + g->blendpixel(x+nx, y+ny, colr, colg, colb, 30); + if (abs(x)+abs(y) <=3 && abs(x)+abs(y)) + g->blendpixel(x+nx, y+ny, colr, colg, colb, 20); + if (abs(x)+abs(y) == 2) + g->blendpixel(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*sim->parts[i].life + flicker; + for (x = 0; gradv>0.5; x++) { + g->addpixel(nx+x, ny, colr, colg, colb, gradv); + g->addpixel(nx-x, ny, colr, colg, colb, gradv); + + g->addpixel(nx, ny+x, colr, colg, colb, gradv); + g->addpixel(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(sim->parts[i].vy)*17; + g->blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); + g->blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + if (gradv>255) gradv=255; + g->blendpixel(nx+1, ny-1, colr, colg, colb, gradv); + g->blendpixel(nx-1, ny-1, colr, colg, colb, gradv); + g->blendpixel(nx+1, ny+1, colr, colg, colb, gradv); + g->blendpixel(nx-1, ny+1, colr, colg, colb, gradv); + for (x = 1; gradv>0.5; x++) { + g->addpixel(nx+x, ny, colr, colg, colb, gradv); + g->addpixel(nx-x, ny, colr, colg, colb, gradv); + g->addpixel(nx, ny+x, colr, colg, colb, gradv); + g->addpixel(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; + g->blendpixel(nx, ny, colr, colg, colb, (gradv*4)>255?255:(gradv*4) ); + g->blendpixel(nx+1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx-1, ny, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx, ny+1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + g->blendpixel(nx, ny-1, colr, colg, colb, (gradv*2)>255?255:(gradv*2) ); + if (gradv>255) gradv=255; + g->blendpixel(nx+1, ny-1, colr, colg, colb, gradv); + g->blendpixel(nx-1, ny-1, colr, colg, colb, gradv); + g->blendpixel(nx+1, ny+1, colr, colg, colb, gradv); + g->blendpixel(nx-1, ny+1, colr, colg, colb, gradv); + for (x = 1; gradv>0.5; x++) { + g->addpixel(nx+x, ny, colr, colg, colb, gradv); + g->addpixel(nx-x, ny, colr, colg, colb, gradv); + g->addpixel(nx, ny+x, colr, colg, colb, gradv); + g->addpixel(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; + sim->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 = ddist*cos(drad); + nyo = ddist*sin(drad); + if (ny+nyo>0 && ny+nyo<YRES && nx+nxo>0 && nx+nxo<XRES) + g->addpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]); + } + } + if (pixel_mode & EFFECT_GRAVOUT) + { + int nxo = 0; + int nyo = 0; + int r; + int fire_bv = 0; + float drad = 0.0f; + float ddist = 0.0f; + sim->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 = ddist*cos(drad); + nyo = ddist*sin(drad); + if (ny+nyo>0 && ny+nyo<YRES && nx+nxo>0 && nx+nxo<XRES) + g->addpixel(nx+nxo, ny+nyo, colr, colg, colb, 255-orbd[r]); + } + } + //Fire effects + if(firea && (pixel_mode & FIRE_BLEND)) + { +#ifdef OGLR + smokeV[csmokeV++] = nx; + smokeV[csmokeV++] = ny; + smokeC[csmokeC++] = ((float)firer)/255.0f; + smokeC[csmokeC++] = ((float)fireg)/255.0f; + smokeC[csmokeC++] = ((float)fireb)/255.0f; + smokeC[csmokeC++] = ((float)firea)/255.0f; + csmoke++; +#else + firea /= 2; + fire_r[ny/CELL][nx/CELL] = (firea*firer + (255-firea)*fire_r[ny/CELL][nx/CELL]) >> 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(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 +} + +void Renderer::prepare_graphicscache() +{ + graphicscache = (gcache_item *)malloc(sizeof(gcache_item)*PT_NUM); + memset(graphicscache, 0, sizeof(gcache_item)*PT_NUM); +} + +void Renderer::draw_other() // EMP effect +{ + int i, j; + //if (emp_decor>0 && !sys_pause) emp_decor-=emp_decor/25+2; TODO: Render should render only, do not change simulation state + if (emp_decor>40) emp_decor=40; + if (emp_decor<0) emp_decor = 0; + if (!(display_mode & DISPLAY_EFFE)) // no 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<YRES; j++) + for (i=0; i<XRES; i++) + { + this->g->drawpixel(i, j, r, g, b, a); + } +#endif + } +} + +void Renderer::draw_grav() +{ + int x, y, i, ca; + float nx, ny, dist; + + for (y=0; y<YRES/CELL; y++) + { + for (x=0; x<XRES/CELL; x++) + { + ca = y*(XRES/CELL)+x; + if(fabsf(sim->gravx[ca]) <= 0.001f && fabsf(sim->gravy[ca]) <= 0.001f) + continue; + nx = x*CELL; + ny = y*CELL; + dist = fabsf(sim->gravy[ca])+fabsf(sim->gravx[ca]); + for(i = 0; i < 4; i++) + { + nx -= sim->gravx[ca]*0.5f; + ny -= sim->gravy[ca]*0.5f; + g->addpixel((int)(nx+0.5f), (int)(ny+0.5f), 255, 255, 255, (int)(dist*20.0f)); + } + } + } +} + +void Renderer::draw_air() +{ +#ifndef OGLR + int x, y, i, j; + float (*pv)[XRES/CELL] = sim->air->pv; + float (*hv)[XRES/CELL] = sim->air->hv; + float (*vx)[XRES/CELL] = sim->air->vx; + float (*vy)[XRES/CELL] = sim->air->vy; + pixel c; + for (y=0; y<YRES/CELL; y++) + for (x=0; x<XRES/CELL; x++) + { + if (display_mode & DISPLAY_AIRP) + { + if (pv[y][x] > 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) + { + 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 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; j<CELL; j++)//draws the colors + for (i=0; i<CELL; i++) + g->vid[(x*CELL+i) + (y*CELL+j)*(XRES+BARSIZE)] = c; + } +#else + GLuint airProg; + if(display_mode & DISPLAY_AIRC) + { + airProg = airProg_Cracker; + } + else if(display_mode & DISPLAY_AIRV) + { + airProg = airProg_Velocity; + } + else if(display_mode & DISPLAY_AIRP) + { + airProg = airProg_Pressure; + } + else + { + return; + } + + glEnable( GL_TEXTURE_2D ); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); + + glUseProgram(airProg); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, airVX); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_RED, GL_FLOAT, vx); + glUniform1i(glGetUniformLocation(airProg, "airX"), 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, airVY); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_GREEN, GL_FLOAT, vy); + glUniform1i(glGetUniformLocation(airProg, "airY"), 1); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, airPV); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, XRES/CELL, YRES/CELL, GL_BLUE, GL_FLOAT, pv); + glUniform1i(glGetUniformLocation(airProg, "airP"), 2); + glActiveTexture(GL_TEXTURE0); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + glTexCoord2d(1, 1); + glVertex3f(XRES*sdl_scale, YRES*sdl_scale, 1.0); + glTexCoord2d(0, 1); + glVertex3f(0, YRES*sdl_scale, 1.0); + glTexCoord2d(0, 0); + glVertex3f(0, 0, 1.0); + glTexCoord2d(1, 0); + glVertex3f(XRES*sdl_scale, 0, 1.0); + glEnd(); + + glUseProgram(0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glDisable( GL_TEXTURE_2D ); +#endif +} + +void Renderer::draw_grav_zones() +{ + int x, y, i, j; + for (y=0; y<YRES/CELL; y++) + { + for (x=0; x<XRES/CELL; x++) + { + //if(sim->gravmask[y*(XRES/CELL)+x]) + { + for (j=0; j<CELL; j++)//draws the colors + for (i=0; i<CELL; i++) + if(i == j) + g->drawpixel(x*CELL+i, y*CELL+j, 255, 200, 0, 120); + else + g->drawpixel(x*CELL+i, y*CELL+j, 32, 32, 32, 120); + } + } + } +} + +void Renderer::init_display_modes() +{ + int i; + colour_mode = COLOUR_DEFAULT; + display_modes = (unsigned int*)calloc(1, sizeof(unsigned int)); + render_modes = (unsigned int*)calloc(2, sizeof(unsigned int)); + + display_modes[0] = 0; + render_modes[0] = RENDER_FIRE; + render_modes[1] = 0; + + 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++; + } +} + +Renderer::Renderer(Graphics * g, Simulation * sim) +{ + this->g = g; + this->sim = sim; + + prepare_alpha(CELL, 1.0f); + init_display_modes(); + prepare_graphicscache(); + + 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}; + + 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}; + + flm_data = Graphics::generate_gradient(flm_data_colours, flm_data_pos, flm_data_points, 200); + plasma_data = Graphics::generate_gradient(plasma_data_colours, plasma_data_pos, plasma_data_points, 200); +} |
