From 96506610b276be1b4bc1cbc462d991237750fc62 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Sat, 21 Apr 2012 22:46:37 +0100 Subject: Clean out graphics, add openGL graphics in seperate file, change brush to use unsigned char rather than boolean for bitmap/outline diff --git a/src/Graphics.cpp b/src/Graphics.cpp index e03a699..665da67 100644 --- a/src/Graphics.cpp +++ b/src/Graphics.cpp @@ -3,56 +3,134 @@ #include #include #include "Config.h" -//#include "simulation/Air.h" -//#include "simulation/Gravity.h" -//#include "powder.h" -//#define INCLUDE_PSTRUCT -//#include "Simulation.h" -//#include "Graphics.h" -//#include "ElementGraphics.h" +#include "Misc.h" +#include "Graphics.h" #define INCLUDE_FONTDATA #include "font.h" -#include "Misc.h" -#include "hmap.h" -//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; +TPT_INLINE void VideoBuffer::BlendPixel(int x, int y, int r, int g, int b, int a) +{ +#ifdef PIX32OGL + pixel t; + if (x<0 || y<0 || x>=Width || y>=Height) + return; + if (a!=255) + { + t = Buffer[y*(Width)+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); + } + Buffer[y*(Width)+x] = PIXRGBA(r,g,b,a); +#else + pixel t; + if (x<0 || y<0 || x>=Width || y>=Height) + return; + if (a!=255) + { + t = Buffer[y*(Width)+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; + } + Buffer[y*(Width)+x] = PIXRGB(r,g,b); +#endif +} -/*#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*/ +TPT_INLINE void VideoBuffer::SetPixel(int x, int y, int r, int g, int b, int a) +{ + if (x<0 || y<0 || x>=Width || y>=Height) + return; +#ifdef PIX32OGL + Buffer[y*(Width)+x] = PIXRGBA(r,g,b,a); +#else + Buffer[y*(Width)+x] = PIXRGB(r,g,b); +#endif +} -/* -int emp_decor = 0; -int sandcolour_r = 0; -int sandcolour_g = 0; -int sandcolour_b = 0; -int sandcolour_frame = 0; +TPT_INLINE void VideoBuffer::AddPixel(int x, int y, int r, int g, int b, int a) +{ + pixel t; + if (x<0 || y<0 || x>=Width || y>=Height) + return; + t = Buffer[y*(Width)+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; + Buffer[y*(Width)+x] = PIXRGB(r,g,b); +} -unsigned char fire_r[YRES/CELL][XRES/CELL]; -unsigned char fire_g[YRES/CELL][XRES/CELL]; -unsigned char fire_b[YRES/CELL][XRES/CELL]; +TPT_INLINE int VideoBuffer::SetCharacter(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; +} -unsigned int fire_alpha[CELL*3][CELL*3]; -pixel *pers_bg; +TPT_INLINE int VideoBuffer::BlendCharacter(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; +} -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}; +TPT_INLINE int VideoBuffer::AddCharacter(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; +} -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};*/ +/** + * Common graphics functions, mostly static methods that provide + * encoding/decoding of different formats and font metrics + */ char * Graphics::GenerateGradient(pixel * colours, float * points, int pointcount, int size) { @@ -227,7 +305,6 @@ pixel *Graphics::resample_img(pixel *src, int sw, int sh, int rw, int rh) int y, x, fxceil, fyceil; //int i,j,x,y,w,h,r,g,b,c; pixel *q = NULL; - //TODO: Actual resampling, this is just cheap nearest pixel crap if(rw == sw && rh == sh){ //Don't resample q = (pixel *)malloc(rw*rh*PIXELSIZE); @@ -346,2030 +423,265 @@ pixel *Graphics::rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f return q; } -#ifdef OGLR -void clearScreenNP(float alpha) -{ - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} -#endif - -//an easy way to draw a blob -void Graphics::drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb) +int Graphics::textwidth(const char *s) { - blendpixel(x+1, y, cr, cg, cb, 112); - blendpixel(x-1, y, cr, cg, cb, 112); - blendpixel(x, y+1, cr, cg, cb, 112); - blendpixel(x, y-1, cr, cg, cb, 112); - - blendpixel(x+1, y-1, cr, cg, cb, 64); - blendpixel(x-1, y-1, cr, cg, cb, 64); - blendpixel(x+1, y+1, cr, cg, cb, 64); - blendpixel(x-1, y+1, cr, cg, cb, 64); + int x = 0; + for (; *s; s++) + x += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + return x-1; } -//draws walls and elements for menu -/*int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc) +int Graphics::textnwidth(char *s, int n) { - int i, j, c; - pixel gc; - if (x > XRES-26 || x < 0) - return 26; - if ((b&0xFF) == PT_LIFE) + int x = 0; + for (; *s; s++) { - for (j=1; j<15; j++) + if (!n) + break; + if(((char)*s)=='\b') { - for (i=1; i<27; i++) - { - vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; - } + s++; + continue; } - c = PIXB(pc) + 3*PIXG(pc) + 2*PIXR(pc); - if (c<544) + x += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + n--; + } + return x-1; +} +void Graphics::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++) { - c = 0; + if (!n) { + break; + } + x += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + if (x>=w) + { + x = 0; + y += FONT_H+2; + } + n--; } - 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) + *cx = x-1; + *cy = y; +} + +int Graphics::textwidthx(char *s, int w) +{ + int x=0,n=0,cw; + for (; *s; s++) { - 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; + s++; + continue; } - else if (ds==2) + cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + if (x+(cw/2) >= w) + break; + x += cw; + n++; + } + return n; +} +int Graphics::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++) { - for (j=1; j<15; j++) - for (i=1; i<27; i++) - vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; + 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; + } + n++; } - else if (ds==4) + } + return n; +} +int Graphics::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++) { - 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++) + if (*s == '\n') { - 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); - } + x = 0; + height += FONT_H+2; } - 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) + else if (*s == '\b') { - for (i=1+(1&(j>>1)); i<13; i+=2) - { - vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; - } + s++; } - for (j=1; j<15; j++) + else { - for (i=14; i<27; i++) + cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + if (x+cw>=width) { - vid_buf[(XRES+BARSIZE)*(y+j)+(x+i)] = pc; + x = 0; + height += FONT_H+2; } - } - 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); + x += cw; } } } - else + return height; +} + +void Graphics::textsize(const char * s, int & width, int & height) +{ + if(!strlen(s)) { - //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 -TPT_INLINE void Graphics::drawpixel(int x, int y, int r, int g, int b, int a) -{ -#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) + width = 0; + height = 0; 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 -} - -inline int Graphics::drawchar(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; -} -inline int Graphics::addchar(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 Graphics::drawtext(int x, int y, std::string &s, int r, int g, int b, int a) -{ - return drawtext(x, y, s.c_str(), r, g, b, a); -} - -int Graphics::drawtext(int x, int y, const char *s, int r, int g, int b, int a) -{ - int sx = x; + int cHeight = FONT_H+2, cWidth = 0, lWidth = 0; for (; *s; s++) { if (*s == '\n') { - x = sx; - y += FONT_H+2; + cWidth = 0; + cHeight += 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(x, y, *(unsigned char *)s, r, g, b, a); - } - return x; -} - -//Draw text with an outline -int Graphics::drawtext_outline(int x, int y, const char *s, int r, int g, int b, int a, int olr, int olg, int olb, int ola) -{ - drawtext(x-1, y-1, s, olr, olg, olb, ola); - drawtext(x+1, y+1, s, olr, olg, olb, ola); - - drawtext(x-1, y+1, s, olr, olg, olb, ola); - drawtext(x+1, y-1, s, olr, olg, olb, ola); - - return drawtext(x, y, s, r, g, b, a); -} -int Graphics::drawtextwrap(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; - } - x = drawchar(x, y, *(unsigned char *)s, r, g, b, a); - } + cWidth += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; + if(cWidth>lWidth) + lWidth = cWidth; } } - - return rh; + width = lWidth; + height = cHeight; } -//draws a rectange, (x,y) are the top left coords. -void Graphics::drawrect(int x, int y, int w, int h, int r, int g, int b, int a) +void Graphics::draw_icon(int x, int y, Icon icon) { - int i; - for (i=0; i<=w; i++) - { - drawpixel(x+i, y, r, g, b, a); - drawpixel(x+i, y+h, r, g, b, a); - } - for (i=1; i=w && x+textwidth(s)>=w+5) - break; - x = drawchar(x, y, *(unsigned char *)s, r, g, b, a); + free(tmp); + return NULL; } - if (*s) - for (i=0; i<3; i++) - x = drawchar(x, y, '.', r, g, b, a); - return x; -} -int Graphics::textnwidth(char *s, int n) -{ - int x = 0; - for (; *s; s++) + i = width*height*3; + if (BZ2_bzBuffToBuffDecompress((char *)tmp, (unsigned *)&i, (char *)image, cmp_size, 0, 0)) { - if (!n) - break; - if(((char)*s)=='\b') - { - s++; - continue; - } - x += font_data[font_ptrs[(int)(*(unsigned char *)s)]]; - n--; - } - return x-1; -} -void Graphics::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; - } - n--; - } - } - *cx = x-1; - *cy = y; -} - -int Graphics::textwidthx(char *s, int w) -{ - int x=0,n=0,cw; - for (; *s; s++) - { - if((char)*s == '\b') - { - s++; - continue; - } - cw = font_data[font_ptrs[(int)(*(unsigned char *)s)]]; - if (x+(cw/2) >= w) - break; - x += cw; - n++; - } - return n; -} -int Graphics::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; - } - n++; - } - } - return n; -} -int Graphics::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; - } - x += cw; - } - } - } - return height; -} - -//the most used function for drawing a pixel, because it has OpenGL support, which is not fully implemented. -TPT_INLINE void Graphics::blendpixel(int x, int y, int r, int g, int b, int a) -{ -#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 Graphics::draw_icon(int x, int y, Icon icon) -{ - switch(icon) - { - case IconOpen: - drawchar(x, y, 0x81, 255, 255, 255, 255); - break; - case IconReload: - drawchar(x, y, 0x91, 255, 255, 255, 255); - break; - case IconSave: - drawchar(x, y, 0x82, 255, 255, 255, 255); - break; - case IconVoteUp: - drawchar(x, y, 0xCB, 0, 187, 18, 255); - break; - case IconVoteDown: - drawchar(x, y, 0xCA, 187, 40, 0, 255); - break; - case IconTag: - drawchar(x, y, 0x83, 255, 255, 255, 255); - break; - case IconNew: - drawchar(x, y, 0x92, 255, 255, 255, 255); - break; - case IconLogin: - drawchar(x, y, 0x84, 255, 255, 255, 255); - break; - case IconSimulationSettings: - drawchar(x, y, 0xCF, 255, 255, 255, 255); - break; - case IconRenderSettings: - addchar(x, y, 0xD8, 255, 0, 0, 255); - addchar(x, y, 0xD9, 0, 255, 0, 255); - addchar(x, y, 0xDA, 0, 0, 255, 255); - break; - case IconPause: - drawchar(x, y, 0x90, 255, 255, 255, 255); - break; - case IconReport: - drawchar(x, y, 0xE3, 255, 255, 0, 255); - break; - case IconFavourite: - drawchar(x, y, 0xCC, 192, 160, 64, 255); - break; - case IconVoteSort: - case IconDateSort: - case IconFolder: - case IconSearch: - case IconDelete: - default: - drawchar(x, y, 't', 255, 255, 255, 255); - break; - } -} - -void Graphics::draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a) //Draws a line -{ - int dx, dy, i, sx, sy, check, e, x, y; - - dx = abs(x1-x2); - dy = abs(y1-y2); - sx = isign(x2-x1); - sy = isign(y2-y1); - x = x1; - y = y1; - check = 0; - - if (dy>dx) - { - 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 Graphics::addpixel(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 Graphics::xor_pixel(int x, int y) -{ - 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 Graphics::xor_line(int x1, int y1, int x2, int y2) -{ - 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 Graphics::blend_line(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 Graphics::xor_rect(int x, int y, int w, int h) -{ - int i; - for (i=0; i>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); - } - } -} - -pixel *Graphics::render_packed_rgb(void *image, int width, int height, int cmp_size) -{ - unsigned char *tmp; - pixel *res; - int i; - - tmp = (unsigned char *)malloc(width*height*3); - if (!tmp) - return NULL; - res = (pixel *)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; i YRES+MENUSIZE) h = (YRES+MENUSIZE)-y; //Adjust height to prevent drawing off the bottom - if(a >= 255) - for (j=0; j0) - r--; - if (g>0) - g--; - if (b>0) - b--; - dst[i] = PIXRGB(r,g,b); - } -} - -void Graphics::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 = (unsigned char *)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 Graphics::render_cursor(pixel *vid, int x, int y, int t, int rx, int ry) -{ -#ifdef OGLR - int i; - if (trx || (j+1)>ry)) - { - xor_pixel(x+i, y+j, vid); - xor_pixel(x-i, y-j, vid); - if (i&&j)xor_pixel(x+i, y-j, vid); - if (i&&j)xor_pixel(x-i, y+j, vid); - } - } - else if (CURRENT_BRUSH==CIRCLE_BRUSH) - { - for (j=0; j<=ry; j++) - for (i=0; i<=rx; i++) - if (pow(i,2)*pow(ry,2)+pow(j,2)*pow(rx,2)<=pow(rx,2)*pow(ry,2) && - (pow(i+1,2)*pow(ry,2)+pow(j,2)*pow(rx,2)>pow(rx,2)*pow(ry,2) || - pow(i,2)*pow(ry,2)+pow(j+1,2)*pow(rx,2)>pow(rx,2)*pow(ry,2))) - { - xor_pixel(x+i, y+j, vid); - if (j) xor_pixel(x+i, y-j, vid); - if (i) xor_pixel(x-i, y+j, vid); - if (i&&j) xor_pixel(x-i, y-j, vid); - } - } - else if (CURRENT_BRUSH==TRI_BRUSH) - { - for (j=-ry; j<=ry; j++) - for (i=-rx; i<=0; i++) - if ((j <= ry ) && ( j >= (((-2.0*ry)/(rx))*i)-ry ) && (j+1>ry || ( j-1 < (((-2.0*ry)/(rx))*i)-ry )) ) - { - xor_pixel(x+i, y+j, vid); - if (i) xor_pixel(x-i, y+j, vid); - } - } - } - else //wall cursor - { - int tc; - c = (rx/CELL) * CELL; - x = (x/CELL) * CELL; - y = (y/CELL) * CELL; - - tc = !((c%(CELL*2))==0); - - x -= c/2; - y -= c/2; - - x += tc*(CELL/2); - y += tc*(CELL/2); - - for (i=0; iparts; - char infobuf[256]; - if(debug_flags & DEBUG_PERFORMANCE_FRAME || debug_flags & DEBUG_PERFORMANCE_CALC) - { - int t1, t2, x = 0, i = debug_perf_istart; - float partiavg = 0, frameavg = 0; - while(i != debug_perf_iend) - { - partiavg += abs(debug_perf_partitime[i]/100000); - frameavg += abs(debug_perf_frametime[i]/100000); - if(debug_flags & DEBUG_PERFORMANCE_CALC) - t1 = abs(debug_perf_partitime[i]/100000); - else - t1 = 0; - - if(debug_flags & DEBUG_PERFORMANCE_FRAME) - t2 = abs(debug_perf_frametime[i]/100000); - else - t2 = 0; - - if(t1 > 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+(lxparts_lastActiveIndex, NPART, (((float)sim->parts_lastActiveIndex)/((float)NPART))*100.0f); - for(i = 0; i < NPART; i++){ - if(parts[i].type){ - drawpixel(vid, x, y, 255, 255, 255, 180); - } else { - drawpixel(vid, x, y, 0, 0, 0, 180); - } - if(i == sim->parts_lastActiveIndex) - { - lpx = x; - lpy = y; - } - x++; - if(x>=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); - } -}*/ - -void Graphics::Clear() -{ - memset(vid, 0, PIXELSIZE * ((XRES+BARSIZE) * (YRES+MENUSIZE))); -#ifdef OGLR - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -#endif -} - -void Graphics::AttachSDLSurface(SDL_Surface * surface) -{ - sdl_scrn = surface; -#ifdef OGLR - SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glOrtho(0, (XRES+BARSIZE)*sdl_scale, 0, (YRES+MENUSIZE)*sdl_scale, -1, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glRasterPos2i(0, (YRES+MENUSIZE)); - glPixelZoom(1, -1); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //Texture for main UI - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &vidBuf); - glBindTexture(GL_TEXTURE_2D, vidBuf); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, XRES+BARSIZE, YRES+MENUSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); - - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); -#endif -} - -void Graphics::Blit() -{ -#ifndef OGLR - if(sdl_scrn) - { - pixel * dst; - pixel * src = vid; - int j, x = 0, y = 0, w = XRES+BARSIZE, h = YRES+MENUSIZE, pitch = XRES+BARSIZE; - if (SDL_MUSTLOCK(sdl_scrn)) - if (SDL_LockSurface(sdl_scrn)<0) - return; - dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x; - for (j=0; jpitch/PIXELSIZE; - src+=pitch; - } - if (SDL_MUSTLOCK(sdl_scrn)) - SDL_UnlockSurface(sdl_scrn); - SDL_UpdateRect(sdl_scrn,0,0,0,0); - } -#else - //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, vid); - 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 ); - glFlush(); - SDL_GL_SwapBuffers (); -#endif -} - -Graphics::Graphics(): - sdl_scrn(NULL) -{ - vid = (pixel *)malloc(PIXELSIZE * ((XRES+BARSIZE) * (YRES+MENUSIZE))); - -#ifdef OGLR -#ifdef WIN32 - status = glewInit(); - if(status != GLEW_OK) - { - fprintf(stderr, "Initializing Glew: %d\n", status); - return 0; - } -#endif -#endif -} - -Graphics::~Graphics() -{ - free(vid); -} diff --git a/src/Graphics.h b/src/Graphics.h index 4e6edf6..df7342b 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -91,92 +91,84 @@ enum Icon IconReport }; +//"Graphics lite" - slightly lower performance due to variable size, +class VideoBuffer +{ +public: + pixel * Buffer; + int Width, Height; + + VideoBuffer(int width, int height): Width(width), Height(height), Buffer((pixel*)calloc(width*height, PIXELSIZE)) { }; + void BlendPixel(int x, int y, int r, int g, int b, int a); + void AddPixel(int x, int y, int r, int g, int b, int a); + void SetPixel(int x, int y, int r, int g, int b, int a); + int BlendCharacter(int x, int y, int c, int r, int g, int b, int a); + int AddCharacter(int x, int y, int c, int r, int g, int b, int a); + int SetCharacter(int x, int y, int c, int r, int g, int b, int a); + ~VideoBuffer() { free(Buffer); }; +}; + class Graphics { public: - SDL_Surface * sdl_scrn; pixel *vid; - pixel *render_packed_rgb(void *image, int width, int height, int cmp_size); + int sdl_scale; +#ifdef OGLR + //OpenGL specific instance variables + GLuint vidBuf, textTexture; +#else + SDL_Surface * sdl_scrn; +#endif + + //Common graphics methods in Graphics.cpp static char * GenerateGradient(pixel * colours, float * points, int pointcount, int size); - //void draw_other(); - void draw_rgba_image(unsigned char *data, int x, int y, float a); + + //PTIF methods static void *ptif_pack(pixel *src, int w, int h, int *result_size); static pixel *ptif_unpack(void *datain, int size, int *w, int *h); static pixel *resample_img_nn(pixel *src, int sw, int sh, int rw, int rh); static pixel *resample_img(pixel *src, int sw, int sh, int rw, int rh); static pixel *rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f); - //void render_gravlensing(pixel *src, pixel * dst); - //void sdl_blit_1(int x, int y, int w, int h, pixel *src, int pitch); - //void sdl_blit_2(int x, int y, int w, int h, pixel *src, int pitch); - //void sdl_blit(int x, int y, int w, int h, pixel *src, int pitch); - inline void drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb); - void draw_tool(int b, int sl, int sr, unsigned pc, unsigned iswall); - //int draw_tool_xy(pixel *vid_buf, int x, int y, int b, unsigned pc); - //void draw_menu(pixel *vid_buf, int i, int hover); - void drawpixel(int x, int y, int r, int g, int b, int a); - inline int addchar(int x, int y, int c, int r, int g, int b, int a); - inline int drawchar(int x, int y, int c, int r, int g, int b, int a); - int drawtext(int x, int y, std::string &s, int r, int g, int b, int a); - int drawtext(int x, int y, const char *s, int r, int g, int b, int a); - int drawtext_outline(int x, int y, const char *s, int r, int g, int b, int a, int olr, int olg, int olb, int ola); - int drawtextwrap(int x, int y, int w, const char *s, int r, int g, int b, int a); - void drawrect(int x, int y, int w, int h, int r, int g, int b, int a); - void fillrect(int x, int y, int w, int h, int r, int g, int b, int a); - void clearrect(int x, int y, int w, int h); - void drawdots(int x, int y, int h, int r, int g, int b, int a); - static int textwidth(char *s); - int drawtextmax(int x, int y, int w, char *s, int r, int g, int b, int a); + static pixel *render_packed_rgb(void *image, int width, int height, int cmp_size); + + //Font/text metrics static int textnwidth(char *s, int n); static void textnpos(char *s, int n, int w, int *cx, int *cy); static int textwidthx(char *s, int w); static int textposxy(char *s, int width, int w, int h); static int textwrapheight(char *s, int width); - inline void blendpixel(int x, int y, int r, int g, int b, int a); + static int textwidth(const char *s); + static void textsize(const char * s, int & width, int & height); + + void blendpixel(int x, int y, int r, int g, int b, int a); + void addpixel(int x, int y, int r, int g, int b, int a); + void draw_icon(int x, int y, Icon icon); - //void draw_air(); - //void draw_grav_zones(pixel *vid); - //void draw_grav(pixel *vid); - void draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a); - inline void addpixel(int x, int y, int r, int g, int b, int a); - void xor_pixel(int x, int y); - void xor_line(int x1, int y1, int x2, int y2); - void xor_rect(int x, int y, int w, int h); - inline void blend_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a); - //void render_parts(pixel *vid); -// #ifdef OGLR -// void draw_parts_fbo(); -// #endif -// void draw_parts(); -// void draw_walls(pixel *vid); -// void create_decorations(int x, int y, int rx, int ry, int r, int g, int b, int click, int tool); -// void create_decoration(int x, int y, int r, int g, int b, int click, int tool); -// 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); -// void box_decorations(int x1, int y1, int x2, int y2, int r, int g, int b, int click, int tool); -// void draw_color_menu(pixel *vid_buf, int i, int hover); - inline void draw_wavelengths(int x, int y, int h, int wl); - //void render_signs(); -// void render_fire(pixel *dst); -// void prepare_alpha(int size, float intensity); - inline void draw_image(pixel *img, int x, int y, int w, int h, int a); - static void dim_copy(pixel *dst, pixel *src); - static void dim_copy_pers(pixel *dst, pixel *src); - //void render_zoom(pixel *img); - //int render_thumb(void *thumb, int size, int bzip2, pixel *vid_buf, int px, int py, int scl); - //void render_cursor(pixel *vid, int x, int y, int t, int rx, int ry); - //int sdl_open(void); - //int draw_debug_info(pixel* vid, int lm, int lx, int ly, int cx, int cy, int line_x, int line_y); + void Clear(); - void Blit(); void AttachSDLSurface(SDL_Surface * surface); - #ifdef OGLR - void clearScreen(float alpha); - void ogl_blit(int x, int y, int w, int h, pixel *src, int pitch, int scale); - #endif + void Blit(); + // + int drawtext(int x, int y, const char *s, int r, int g, int b, int a); + int drawtext(int x, int y, std::string s, int r, int g, int b, int a); + int drawchar(int x, int y, int c, int r, int g, int b, int a); + int addchar(int x, int y, int c, int r, int g, int b, int a); + + void xor_pixel(int x, int y); + void xor_line(int x, int y, int x2, int y2); + void xor_rect(int x, int y, int width, int height); + void xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h); + + void draw_line(int x, int y, int x2, int y2, int r, int g, int b, int a); + void drawrect(int x, int y, int width, int height, int r, int g, int b, int a); + void fillrect(int x, int y, int width, int height, int r, int g, int b, int a); + void clearrect(int x, int y, int width, int height); + void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2); + + void draw_image(pixel *img, int x, int y, int w, int h, int a); + Graphics(); ~Graphics(); -#ifdef OGLR - GLuint vidBuf; -#endif }; #endif diff --git a/src/OpenGLGraphics.cpp b/src/OpenGLGraphics.cpp new file mode 100644 index 0000000..ed2b2ab --- /dev/null +++ b/src/OpenGLGraphics.cpp @@ -0,0 +1,399 @@ +#include "Graphics.h" +#include "font.h" + +#ifdef OGLR + +Graphics::Graphics(): +sdl_scale(1) +{ + +} + +Graphics::~Graphics() +{ +} + +void Graphics::Clear() +{ + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); +} + +void Graphics::AttachSDLSurface(SDL_Surface * surface) +{ + //sdl_scrn = surface; + SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + //glOrtho(0, (XRES+BARSIZE)*sdl_scale, 0, (YRES+MENUSIZE)*sdl_scale, -1, 1); + glOrtho(0, (XRES+BARSIZE)*sdl_scale, (YRES+MENUSIZE)*sdl_scale, 0, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + + //glRasterPos2i(0, (YRES+MENUSIZE)); + glRasterPos2i(0, 0); + glPixelZoom(1, 1); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //Texture for main UI + glEnable(GL_TEXTURE_2D); + + glGenTextures(1, &vidBuf); + glBindTexture(GL_TEXTURE_2D, vidBuf); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, XRES+BARSIZE, YRES+MENUSIZE, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + + glBindTexture(GL_TEXTURE_2D, 0); + + glGenTextures(1, &textTexture); + glBindTexture(GL_TEXTURE_2D, textTexture); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glBindTexture(GL_TEXTURE_2D, 0); + + glDisable(GL_TEXTURE_2D); +} + +void Graphics::Blit() +{ + //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, vid); + 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 );*/ + glFlush(); + SDL_GL_SwapBuffers (); +} + +int Graphics::drawtext(int x, int y, const char *s, int r, int g, int b, int a) +{ + if(!strlen(s)) + return 0; + int width, height; + Graphics::textsize(s, width, height); + VideoBuffer texture(width, height); + int characterX = 0, characterY = 0; + int startX = characterX; + for (; *s; s++) + { + if (*s == '\n') + { + characterX = startX; + characterY += 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 + { + characterX = texture.SetCharacter(characterX, characterY, *(unsigned char *)s, r, g, b, a); + } + } + glEnable(GL_TEXTURE_2D); + + //Generate texture + glBindTexture(GL_TEXTURE_2D, textTexture); + + //Draw texture + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.Width, texture.Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture.Buffer); + + //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture.Width, texture.Height, GL_BGRA, GL_UNSIGNED_BYTE, texture.Buffer); + glBegin(GL_QUADS); + glTexCoord2d(0, 0); + glVertex2f(x, y); + glTexCoord2d(1, 0); + glVertex2f(x+texture.Width, y); + glTexCoord2d(1, 1); + glVertex2f(x+texture.Width, y+texture.Height); + glTexCoord2d(0, 1); + glVertex2f(x, y+texture.Height); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + return x; +} + +int Graphics::drawtext(int x, int y, std::string s, int r, int g, int b, int a) +{ + return drawtext(x, y, s.c_str(), r, g, b, a); +} + +TPT_INLINE int Graphics::drawchar(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++); + VideoBuffer texture(w, 12); + texture.SetCharacter(0, 0, c, r, g, b, a); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, textTexture); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.Width, texture.Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture.Buffer); + glBegin(GL_QUADS); + glTexCoord2d(0, 0); + glVertex2f(x, y); + glTexCoord2d(1, 0); + glVertex2f(x+texture.Width, y); + glTexCoord2d(1, 1); + glVertex2f(x+texture.Width, y+texture.Height); + glTexCoord2d(0, 1); + glVertex2f(x, y+texture.Height); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + return x + w; +} + +TPT_INLINE int Graphics::addchar(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++); + VideoBuffer texture(w, 12); + texture.AddCharacter(0, 0, c, r, g, b, a); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, textTexture); + glBlendFunc(GL_ONE, GL_ONE); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.Width, texture.Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture.Buffer); + glBegin(GL_QUADS); + glTexCoord2d(0, 0); + glVertex2f(x, y); + glTexCoord2d(1, 0); + glVertex2f(x+texture.Width, y); + glTexCoord2d(1, 1); + glVertex2f(x+texture.Width, y+texture.Height); + glTexCoord2d(0, 1); + glVertex2f(x, y+texture.Height); + glEnd(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + return x + w; +} + +TPT_INLINE void Graphics::xor_pixel(int x, int y) +{ + //OpenGL doesn't support single pixel manipulation, there are ways around it, but with poor performance +} + +TPT_INLINE void Graphics::blendpixel(int x, int y, int r, int g, int b, int a) +{ + //OpenGL doesn't support single pixel manipulation, there are ways around it, but with poor performance +} + +TPT_INLINE void Graphics::addpixel(int x, int y, int r, int g, int b, int a) +{ + //OpenGL doesn't support single pixel manipulation, there are ways around it, but with poor performance +} + +void Graphics::xor_line(int x, int y, int x2, int y2) +{ + glEnable(GL_COLOR_LOGIC_OP); + //glEnable(GL_LINE_SMOOTH); + glLogicOp(GL_XOR); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_LINES); + glVertex2i(x, y); + glVertex2i(x2, y2); + glEnd(); + glDisable(GL_COLOR_LOGIC_OP); +} + +void Graphics::xor_rect(int x, int y, int width, int height) +{ + 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); + glVertex2i(x, y); + glVertex2i(x+width, y); + glVertex2i(x+width, y+height); + glVertex2i(x, y+height); + glVertex2i(x, y); + glEnd(); + glDisable(GL_COLOR_LOGIC_OP); +} + +void Graphics::xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h) +{ + //glEnable(GL_COLOR_LOGIC_OP); + //glLogicOp(GL_XOR); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, textTexture); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + glBegin(GL_QUADS); + glTexCoord2d(0, 0); + glVertex2f(x, y); + glTexCoord2d(1, 0); + glVertex2f(x+w, y); + glTexCoord2d(1, 1); + glVertex2f(x+w, y+h); + glTexCoord2d(0, 1); + glVertex2f(x, y+h); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + //glDisable(GL_COLOR_LOGIC_OP); +} + +void Graphics::draw_line(int x, int y, int x2, int y2, int r, int g, int b, int a) +{ + a = 255; + glColor4ub(r, g, b, a); + glBegin(GL_LINES); + glVertex2i(x, y); + glVertex2i(x2, y2); + glEnd(); +} + +void Graphics::drawrect(int x, int y, int width, int height, int r, int g, int b, int a) +{ + x++; + glColor4ub(r, g, b, a); + glBegin(GL_LINE_STRIP); + glVertex2i(x, y); + glVertex2i(x+width, y); + glVertex2i(x+width, y+height); + glVertex2i(x, y+height+1); //+1 is a hack to prevent squares from missing their corners, will make smoothed lines look like SHIT + glVertex2i(x, y); + glEnd(); +} + +void Graphics::fillrect(int x, int y, int width, int height, int r, int g, int b, int a) +{ + x++; + y++; + width-=1; + height-=1; + + glColor4ub(r, g, b, a); + glBegin(GL_QUADS); + glVertex2i(x, y); + glVertex2i(x+width, y); + glVertex2i(x+width, y+height); + glVertex2i(x, y+height); + glEnd(); +} + +void Graphics::gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2) +{ + glBegin(GL_QUADS); + glColor4ub(r, g, b, a); + glVertex2i(x, y); + glColor4ub(r2, g2, b2, a2); + glVertex2i(x+width, y); + glColor4ub(r2, g2, b2, a2); + glVertex2i(x+width, y+height); + glColor4ub(r, g, b, a); + glVertex2i(x, y+height); + glEnd(); +} + +void Graphics::clearrect(int x, int y, int width, int height) +{ + glColor4ub(0, 0, 0, 255); + glBegin(GL_QUADS); + glVertex2i(x, y); + glVertex2i(x+width, y); + glVertex2i(x+width, y+height); + glVertex2i(x, y+height); + glEnd(); +} + +void Graphics::draw_image(pixel *img, int x, int y, int w, int h, int a) +{ + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, textTexture); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, img); + glBegin(GL_QUADS); + glTexCoord2d(0, 0); + glVertex2f(x, y); + glTexCoord2d(1, 0); + glVertex2f(x+w, y); + glTexCoord2d(1, 1); + glVertex2f(x+w, y+h); + glTexCoord2d(0, 1); + glVertex2f(x, y+h); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); +} + +#endif diff --git a/src/RasterGraphics.cpp b/src/RasterGraphics.cpp new file mode 100644 index 0000000..472ae3c --- /dev/null +++ b/src/RasterGraphics.cpp @@ -0,0 +1,380 @@ +#include "Graphics.h" +#include "font.h" + +#ifndef OGLR + +Graphics::Graphics(): +sdl_scale(1) +{ + vid = (pixel *)malloc(PIXELSIZE * ((XRES+BARSIZE) * (YRES+MENUSIZE))); + +} + +Graphics::~Graphics() +{ + free(vid); +} + +void Graphics::Clear() +{ + memset(vid, 0, PIXELSIZE * ((XRES+BARSIZE) * (YRES+MENUSIZE))); +} + +void Graphics::AttachSDLSurface(SDL_Surface * surface) +{ + sdl_scrn = surface; +} + +void Graphics::Blit() +{ + if(sdl_scrn) + { + pixel * dst; + pixel * src = vid; + int j, x = 0, y = 0, w = XRES+BARSIZE, h = YRES+MENUSIZE, pitch = XRES+BARSIZE; + if (SDL_MUSTLOCK(sdl_scrn)) + if (SDL_LockSurface(sdl_scrn)<0) + return; + dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x; + for (j=0; jpitch/PIXELSIZE; + src+=pitch; + } + if (SDL_MUSTLOCK(sdl_scrn)) + SDL_UnlockSurface(sdl_scrn); + SDL_UpdateRect(sdl_scrn,0,0,0,0); + } +} + +int Graphics::drawtext(int x, int y, const char *s, int r, int g, int b, int a) +{ + if(!strlen(s)) + return 0; + int width, height; + + int characterX = x, characterY = y; + int startX = characterX; + for (; *s; s++) + { + if (*s == '\n') + { + characterX = startX; + characterY += 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 + { + characterX = drawchar(characterX, characterY, *(unsigned char *)s, r, g, b, a); + } + } + return x; +} + +int Graphics::drawtext(int x, int y, std::string s, int r, int g, int b, int a) +{ + return drawtext(x, y, s.c_str(), r, g, b, a); +} + +TPT_INLINE int Graphics::drawchar(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; +} + +TPT_INLINE int Graphics::addchar(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; +} + +TPT_INLINE void Graphics::xor_pixel(int x, int y) +{ + 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); +} + +TPT_INLINE void Graphics::blendpixel(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; + 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); +} + +TPT_INLINE void Graphics::addpixel(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); +} + +void Graphics::xor_line(int x1, int y1, int x2, int y2) +{ + 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; + } + } +} + +void Graphics::xor_rect(int x, int y, int w, int h) +{ + int i; + for (i=0; iabs(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; + } + } +} + +void Graphics::drawrect(int x, int y, int w, int h, int r, int g, int b, int a) +{ + int i; + for (i=0; i<=w; i++) + { + blendpixel(x+i, y, r, g, b, a); + blendpixel(x+i, y+h, r, g, b, a); + } + for (i=1; i YRES+MENUSIZE) h = (YRES+MENUSIZE)-y; //Adjust height to prevent drawing off the bottom + if(a >= 255) + for (j=0; j>1)&1; idrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==2) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==3) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + drawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); } else if (wtypes[wt].drawstyle==4) { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + 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)); + 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); + drawblob((x*CELL+i), (y*CELL+j), 0x20, 0x20, 0x20); } if (bmap[y][x]==WL_EWALL) { @@ -479,14 +493,14 @@ void Renderer::DrawWalls() for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); + drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } else { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); + drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } } else if (bmap[y][x]==WL_WALLELEC) @@ -495,9 +509,9 @@ void Renderer::DrawWalls() for (i=0; idrawblob((x*CELL+i), (y*CELL+j), PIXR(pc), PIXG(pc), PIXB(pc)); + 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); + drawblob((x*CELL+i), (y*CELL+j), 0x80, 0x80, 0x80); } } else if (bmap[y][x]==WL_EHOLE) @@ -506,7 +520,7 @@ void Renderer::DrawWalls() { for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); + drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); for (j=0; jdrawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); + drawblob((x*CELL+i), (y*CELL+j), 0x24, 0x24, 0x24); } } } @@ -535,6 +549,7 @@ void Renderer::DrawWalls() } } +#endif } void Renderer::get_sign_pos(int i, int *x0, int *y0, int *w, int *h) @@ -577,6 +592,10 @@ void Renderer::DrawSigns() { int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq; sign *signs = sim->signs; +#ifdef OGLR + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); + glTranslated(0, MENUSIZE, 0); +#endif for (i=0; i 18) ? -1 : 1; +#ifdef OGLR + glBegin(GL_LINES); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glVertex2i(x, y); + glVertex2i(x+(dx*4), y+(dy*4)); + glEnd(); +#else for (j=0; j<4; j++) { - g->drawpixel(x, y, 192, 192, 192, 255); + g->blendpixel(x, y, 192, 192, 192, 255); x+=dx; y+=dy; } +#endif /*if (MSIGN==i) { bq = b; @@ -642,10 +669,15 @@ void Renderer::DrawSigns() signs[i].y = my; }*/ } +#ifdef OGLR + glTranslated(0, -MENUSIZE, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#endif } void Renderer::render_gravlensing() { +#ifndef OGLR int nx, ny, rx, ry, gx, gy, bx, by, co; int r, g, b; pixel t; @@ -675,27 +707,15 @@ void Renderer::render_gravlensing() 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);*/ } } +#endif } void Renderer::render_fire() { +#ifndef OGLR int i,j,x,y,r,g,b,nx,ny; for (j=0; j4 ? g-4 : 0; fire_b[j][i] = b>4 ? b-4 : 0; } +#endif } float temp[CELL*3][CELL*3]; @@ -840,6 +861,7 @@ void Renderer::render_parts() glGetIntegerv(GL_BLEND_DST, &origBlendDst); //Render to the particle FBO glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); + glTranslated(0, MENUSIZE, 0); #else /*if (GRID_MODE)//draws the grid { @@ -878,27 +900,6 @@ void Renderer::render_parts() 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) { @@ -1758,10 +1759,9 @@ void Renderer::render_parts() glDisableClientState(GL_VERTEX_ARRAY); //Reset FBO + glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - //Drawing the FBO onto the screen sounds like a cool idea now - glBlendFunc(origBlendSrc, origBlendDst); #endif } @@ -1777,6 +1777,8 @@ void Renderer::draw_other() // EMP effect if (emp_decor>0) { #ifdef OGLR + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); + glTranslated(0, MENUSIZE, 0); 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; @@ -1791,6 +1793,8 @@ void Renderer::draw_other() // EMP effect glVertex2f(XRES, YRES+MENUSIZE); glVertex2f(0, YRES+MENUSIZE); glEnd(); + glTranslated(0, -MENUSIZE, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); #else int r=emp_decor*2.5, g=100+emp_decor*1.5, b=255; int a=(1.0*emp_decor/110)*255; @@ -1801,7 +1805,7 @@ void Renderer::draw_other() // EMP effect for (j=0; jg->drawpixel(i, j, r, g, b, a); + this->g->blendpixel(i, j, r, g, b, a); } #endif } @@ -1926,6 +1930,7 @@ void Renderer::draw_air() glEnable( GL_TEXTURE_2D ); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, partsFbo); + glTranslated(0, MENUSIZE, 0); glUseProgram(airProg); @@ -1957,6 +1962,7 @@ void Renderer::draw_air() glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); + glTranslated(0, -MENUSIZE, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glDisable( GL_TEXTURE_2D ); #endif @@ -1974,14 +1980,27 @@ void Renderer::draw_grav_zones() for (j=0; jdrawpixel(x*CELL+i, y*CELL+j, 255, 200, 0, 120); + g->blendpixel(x*CELL+i, y*CELL+j, 255, 200, 0, 120); else - g->drawpixel(x*CELL+i, y*CELL+j, 32, 32, 32, 120); + g->blendpixel(x*CELL+i, y*CELL+j, 32, 32, 32, 120); } } } } +void Renderer::drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb) +{ + g->blendpixel(x+1, y, cr, cg, cb, 112); + g->blendpixel(x-1, y, cr, cg, cb, 112); + g->blendpixel(x, y+1, cr, cg, cb, 112); + g->blendpixel(x, y-1, cr, cg, cb, 112); + + g->blendpixel(x+1, y-1, cr, cg, cb, 64); + g->blendpixel(x-1, y-1, cr, cg, cb, 64); + g->blendpixel(x+1, y+1, cr, cg, cb, 64); + g->blendpixel(x-1, y+1, cr, cg, cb, 64); +} + Renderer::Renderer(Graphics * g, Simulation * sim): sim(NULL), g(NULL), diff --git a/src/Renderer.h b/src/Renderer.h index b69108a..803a486 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -89,6 +89,7 @@ public: void loadShaders(); #endif + void drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb); //... void get_sign_pos(int i, int *x0, int *y0, int *w, int *h); diff --git a/src/cat/LuaScriptInterface.cpp b/src/cat/LuaScriptInterface.cpp index 5d07279..a918ff1 100644 --- a/src/cat/LuaScriptInterface.cpp +++ b/src/cat/LuaScriptInterface.cpp @@ -1444,7 +1444,7 @@ int luatpt_get_property(lua_State* l) int luatpt_drawpixel(lua_State* l) { - int x, y, r, g, b, a; + /*int x, y, r, g, b, a; x = luaL_optint(l, 1, 0); y = luaL_optint(l, 2, 0); r = luaL_optint(l, 3, 255); @@ -1466,8 +1466,8 @@ int luatpt_drawpixel(lua_State* l) { luacon_g->drawpixel(x, y, r, g, b, a); return 0; - } - return luaL_error(l, "Screen buffer does not exist"); + }*/ + return luaL_error(l, "Deprecated"); } int luatpt_drawrect(lua_State* l) @@ -1496,11 +1496,7 @@ int luatpt_drawrect(lua_State* l) if (b>255) b = 255; if (a<0) a = 0; if (a>255) a = 255; - if (luacon_g->vid!=NULL) - { - luacon_g->drawrect(x, y, w, h, r, g, b, a); - return 0; - } + luacon_g->drawrect(x, y, w, h, r, g, b, a); return luaL_error(l, "Screen buffer does not exist"); } @@ -1530,11 +1526,7 @@ int luatpt_fillrect(lua_State* l) if (b>255) b = 255; if (a<0) a = 0; if (a>255) a = 255; - if (luacon_g->vid!=NULL) - { - luacon_g->fillrect(x, y, w, h, r, g, b, a); - return 0; - } + luacon_g->fillrect(x, y, w, h, r, g, b, a); return luaL_error(l, "Screen buffer does not exist"); } @@ -1559,11 +1551,7 @@ int luatpt_drawline(lua_State* l) if (b>255) b = 255; if (a<0) a = 0; if (a>255) a = 255; - if (luacon_g->vid!=NULL) - { - luacon_g->blend_line(x1, y1, x2, y2, r, g, b, a); - return 0; - } + luacon_g->draw_line(x1, y1, x2, y2, r, g, b, a); return luaL_error(l, "Screen buffer does not exist"); } diff --git a/src/console/ConsoleView.cpp b/src/console/ConsoleView.cpp index f36a33b..cda871e 100644 --- a/src/console/ConsoleView.cpp +++ b/src/console/ConsoleView.cpp @@ -88,8 +88,8 @@ void ConsoleView::OnDraw() { Graphics * g = ui::Engine::Ref().g; g->fillrect(Position.X, Position.Y, Size.X, Size.Y, 0, 0, 0, 110); - g->blend_line(Position.X, Position.Y+Size.Y-16, Position.X+Size.X, Position.Y+Size.Y-16, 255, 255, 255, 160); - g->blend_line(Position.X, Position.Y+Size.Y, Position.X+Size.X, Position.Y+Size.Y, 255, 255, 255, 200); + g->draw_line(Position.X, Position.Y+Size.Y-16, Position.X+Size.X, Position.Y+Size.Y-16, 255, 255, 255, 160); + g->draw_line(Position.X, Position.Y+Size.Y, Position.X+Size.X, Position.Y+Size.Y, 255, 255, 255, 200); } ConsoleView::~ConsoleView() { diff --git a/src/game/Brush.h b/src/game/Brush.h index 98d1321..656f9f3 100644 --- a/src/game/Brush.h +++ b/src/game/Brush.h @@ -8,14 +8,16 @@ #ifndef BRUSH_H_ #define BRUSH_H_ +#include #include "interface/Point.h" class Brush { protected: - bool * outline; - bool * bitmap; + unsigned char * outline; + unsigned char * bitmap; ui::Point size; + ui::Point radius; void updateOutline() { if(!bitmap) @@ -24,35 +26,35 @@ protected: return; if(outline) free(outline); - int width = size.X*2; - int height = size.Y*2; - outline = (bool *)malloc(sizeof(bool)*((width+1)*(height+1))); - for(int x = 0; x <= width; x++) + outline = (unsigned char *)calloc(size.X*size.Y, sizeof(unsigned char)); + for(int x = 0; x < size.X; x++) { - for(int y = 0; y <= height; y++) + for(int y = 0; y < size.Y; y++) { - if(bitmap[y*width+x] && (!y || !x || y == height || x == width || !bitmap[y*width+(x+1)] || !bitmap[y*width+(x-1)] || !bitmap[(y-1)*width+x] || !bitmap[(y+1)*width+x])) - outline[y*width+x] = true; + if(bitmap[y*size.X+x] && (!y || !x || y == size.X-1 || x == size.Y-1 || !bitmap[y*size.X+(x+1)] || !bitmap[y*size.X+(x-1)] || !bitmap[(y-1)*size.X+x] || !bitmap[(y+1)*size.X+x])) + outline[y*size.X+x] = 255; else - outline[y*width+x] = false; + outline[y*size.X+x] = 0; } } } public: Brush(ui::Point size_): bitmap(NULL), - size(size_), - outline(NULL) + outline(NULL), + radius(0, 0), + size(0, 0) { - + SetRadius(size_); }; ui::Point GetRadius() { - return size; + return radius; } - void SetRadius(ui::Point size) + void SetRadius(ui::Point radius) { - this->size = size; + this->radius = radius; + this->size = radius+radius+ui::Point(1, 1); GenerateBitmap(); updateOutline(); } @@ -93,37 +95,30 @@ public: updateOutline(); if(!outline) return; - for(int x = 0; x <= size.X*2; x++) - { - for(int y = 0; y <= size.Y*2; y++) - { - if(outline[y*(size.X*2)+x]) - g->xor_pixel(position.X-size.X+x, position.Y-size.Y+y); - } - } + g->xor_bitmap(outline, position.X-radius.X, position.Y-radius.Y-1, size.X, size.Y); } virtual void GenerateBitmap() { if(bitmap) free(bitmap); - bitmap = (bool *)malloc(sizeof(bool)*(((size.X*2)+1)*((size.Y*2)+1))); - for(int x = 0; x <= size.X*2; x++) + bitmap = (unsigned char *)calloc((size.X*size.Y), sizeof(unsigned char)); + for(int x = 0; x < size.X; x++) { - for(int y = 0; y <= size.Y*2; y++) + for(int y = 0; y < size.Y; y++) { - bitmap[y*(size.X*2)+x] = true; + bitmap[(y*size.X)+x] = 255; } } } //Get a bitmap for drawing particles - bool * GetBitmap() + unsigned char * GetBitmap() { if(!bitmap) GenerateBitmap(); return bitmap; } - bool * GetOutline() + unsigned char * GetOutline() { if(!outline) updateOutline(); diff --git a/src/game/EllipseBrush.h b/src/game/EllipseBrush.h index 0953c01..26b3cf8 100644 --- a/src/game/EllipseBrush.h +++ b/src/game/EllipseBrush.h @@ -22,20 +22,20 @@ public: { if(bitmap) free(bitmap); - bitmap = (bool *)malloc(sizeof(bool)*(((size.X*2)+1)*((size.Y*2)+1))); - int rx = size.X; - int ry = size.Y; - for(int x = 0; x <= size.X*2; x++) + bitmap = (unsigned char*)calloc((size.X*size.Y), sizeof(unsigned char)); + int rx = radius.X; + int ry = radius.Y; + for(int x = 0; x <= radius.X*2; x++) { - for(int y = 0; y <= size.Y*2; y++) + for(int y = 0; y <= radius.Y*2; y++) { - if((pow(x-size.X,2)*pow(ry,2)+pow(y-size.Y,2)*pow(rx,2)<=pow(rx,2)*pow(ry,2))) + if((pow(x-radius.X,2)*pow(ry,2)+pow(y-radius.Y,2)*pow(rx,2)<=pow(rx,2)*pow(ry,2))) { - bitmap[y*(size.X*2)+x] = true; + bitmap[y*(size.X)+x] = 255; } else { - bitmap[y*(size.X*2)+x] = false; + bitmap[y*(size.X)+x] = 0; } } } diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index f289f49..4f94ab8 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -580,6 +580,9 @@ void GameController::ReloadSim() std::string GameController::ElementResolve(int type) { - return std::string(gameModel->GetSimulation()->ptypes[type].name); + if(gameModel && gameModel->GetSimulation() && gameModel->GetSimulation()->ptypes && type >= 0 && type < PT_NUM) + return std::string(gameModel->GetSimulation()->ptypes[type].name); + else + return ""; } diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 219c6ee..7e04c6e 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -857,9 +857,8 @@ void GameView::OnDraw() ren->draw_air(); ren->render_parts(); ren->render_fire(); - //ren->draw_grav(); + ren->draw_grav(); ren->DrawWalls(); - ren->FinaliseParts(); if(activeBrush && currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES) { if(drawMode==DrawRect && isMouseDown) @@ -875,8 +874,9 @@ void GameView::OnDraw() activeBrush->RenderPoint(g, c->PointTranslate(currentMouse)); } } - ren->RenderZoom(); ren->DrawSigns(); + ren->FinaliseParts(); + ren->RenderZoom(); if(selectMode!=SelectNone) { diff --git a/src/interface/Engine.cpp b/src/interface/Engine.cpp index 751cbcb..aea89e7 100644 --- a/src/interface/Engine.cpp +++ b/src/interface/Engine.cpp @@ -74,7 +74,10 @@ void Engine::ShowWindow(Window * window) prevBuffers.push(lastBuffer); } lastBuffer = (pixel*)malloc((width_ * height_) * PIXELSIZE); + +#ifndef OGLR memcpy(lastBuffer, g->vid, (width_ * height_) * PIXELSIZE); +#endif windows.push(state_); } @@ -167,7 +170,9 @@ void Engine::Draw() if(lastBuffer && !(state_->Position.X == 0 && state_->Position.Y == 0 && state_->Size.X == width_ && state_->Size.Y == height_)) { g->Clear(); +#ifndef OGLR memcpy(g->vid, lastBuffer, (width_ * height_) * PIXELSIZE); +#endif } else { diff --git a/src/interface/Slider.cpp b/src/interface/Slider.cpp index 06d6f87..3430ca1 100644 --- a/src/interface/Slider.cpp +++ b/src/interface/Slider.cpp @@ -16,7 +16,9 @@ Slider::Slider(Point position, Point size, int steps): sliderSteps(steps), sliderPosition(0), isMouseDown(false), - bgGradient(NULL) + bgGradient(NULL), + col1(0, 0, 0, 0), + col2(0, 0, 0, 0) { // TODO Auto-generated constructor stub @@ -79,6 +81,8 @@ void Slider::SetColour(Colour col1, Colour col2) { if(bgGradient) free(bgGradient); + this->col1 = col1; + this->col2 = col2; bgGradient = (unsigned char*)Graphics::GenerateGradient( (pixel[2]){PIXRGB(col1.Red, col1.Green, col1.Blue), PIXRGB(col2.Red, col2.Green, col2.Blue)}, (float[2]){0.0f, 1.0f}, 2, Size.X-6); @@ -100,9 +104,13 @@ void Slider::Draw(const Point& screenPos) if(bgGradient) { +#ifndef OGLR for (int j = 3; j < Size.Y-6; j++) for (int i = 3; i < Size.X-6; i++) - g->drawpixel(screenPos.X+i+2, screenPos.Y+j+2, bgGradient[(i-3)*3], bgGradient[(i-3)*3+1], bgGradient[(i-3)*3+2], 255); + g->blendpixel(screenPos.X+i+2, screenPos.Y+j+2, bgGradient[(i-3)*3], bgGradient[(i-3)*3+1], bgGradient[(i-3)*3+2], 255); +#else + g->gradientrect(screenPos.X+3, screenPos.Y+3, Size.X-6, Size.Y-6, col1.Red, col1.Green, col1.Blue, col1.Alpha, col2.Red, col2.Green, col2.Blue, col2.Alpha); +#endif } g->drawrect(screenPos.X+3, screenPos.Y+3, Size.X-6, Size.Y-6, 255, 255, 255, 255); diff --git a/src/interface/Slider.h b/src/interface/Slider.h index 4992f80..21792bc 100644 --- a/src/interface/Slider.h +++ b/src/interface/Slider.h @@ -26,6 +26,7 @@ class Slider: public ui::Component { bool isMouseDown; unsigned char * bgGradient; SliderAction * actionCallback; + Colour col1, col2; void updatePosition(int position); public: Slider(Point position, Point size, int steps); diff --git a/src/interface/Spinner.cpp b/src/interface/Spinner.cpp index 1ecad8d..b988674 100644 --- a/src/interface/Spinner.cpp +++ b/src/interface/Spinner.cpp @@ -27,7 +27,7 @@ void Spinner::Draw(const Point& screenPos) int baseY = screenPos.Y+(Size.Y/2); for(float t = 0.0f; t < 1.0f; t+=0.05f) { - g->drawblob(baseX+(sin(cValue+t)*(Size.X/2)), baseY+(cos(cValue+t)*(Size.X/2)), t*255, t*255, t*255); + //g->drawblob(baseX+(sin(cValue+t)*(Size.X/2)), baseY+(cos(cValue+t)*(Size.X/2)), t*255, t*255, t*255); } } Spinner::~Spinner() diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index eabdcfd..9f435f0 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -434,7 +434,7 @@ void Simulation::ApplyDecorationPoint(int x, int y, int rx, int ry, int colR, in return; } - bool *bitmap = cBrush->GetBitmap(); + unsigned char *bitmap = cBrush->GetBitmap(); for (j=-ry; j<=ry; j++) for (i=-rx; i<=rx; i++) if(bitmap[(j+ry)*(rx*2)+(i+rx)]) @@ -624,10 +624,10 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru } else if(cBrush) { - bool *bitmap = cBrush->GetBitmap(); + unsigned char *bitmap = cBrush->GetBitmap(); for (j=-ry; j<=ry; j++) for (i=-rx; i<=rx; i++) - if(bitmap[(j+ry)*(rx*2)+(i+rx)]) + if(bitmap[(j+ry)*((rx*2)+1)+(i+rx+1)]) delete_part(x+i, y+j, 0); } else @@ -647,10 +647,10 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru } else if(cBrush) { - bool *bitmap = cBrush->GetBitmap(); + unsigned char *bitmap = cBrush->GetBitmap(); for (j=-ry; j<=ry; j++) for (i=-rx; i<=rx; i++) - if(bitmap[(j+ry)*(rx*2)+(i+rx)]) + if(bitmap[(j+ry)*((rx*2)+1)+(i+rx+1)]) { if ( x+i<0 || y+j<0 || x+i>=XRES || y+j>=YRES) continue; @@ -678,10 +678,10 @@ int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Bru } else if(cBrush) { - bool *bitmap = cBrush->GetBitmap(); + unsigned char *bitmap = cBrush->GetBitmap(); for (j=-ry; j<=ry; j++) for (i=-rx; i<=rx; i++) - if(bitmap[(j+ry)*(rx*2)+(i+rx)]) + if(bitmap[(j+ry)*((rx*2)+1)+(i+rx+1)]) if (create_part_add_props(-2, x+i, y+j, c, rx, ry)==-1) f = 1; } -- cgit v0.9.2-21-gd62e