#include"mx3d.h" #include #include namespace mx3d { class mxColor { public: unsigned char r,g,b; mxColor(unsigned char r, unsigned char g, unsigned char b) { this->r = r, this->g = g, this->b = b; } mxColor() { r = g = b = 0; } // copy color void operator=(mxColor &c) { this->r = c.r, this->g = c.g, this->b = c.b; } D3DCOLOR toD3D() { return D3DCOLOR_XRGB(r,g,b); } COLORREF toCol() { return RGB(r,g,b); } }; class mxTexture { public: int width, height; mxTexture() { pbits = 0; color_key = 0xFF00FF; } ~mxTexture() { if(pbits) delete [] pbits; } // Copy texture void operator=(mxTexture &t) { if(pbits) delete [] pbits; pbits = new mxColor [t.width*t.height]; this->width = t.width; this->height = t.height; for(int c = 0; c < t.width*t.height; c++) { pbits[c] = t.pbits[c]; } } void SetPixel(int x, int y, mxColor &c) { pbits[y*width+x] = c; } mxColor &GetPixel(int x, int y) { return pbits[y*width+x]; } bool LoadBMP(std::string source) { FILE *fptr = 0; long offset, size; short type, bitcount; if(pbits) { delete [] pbits; pbits = 0; } fptr = fopen(source.c_str(),"rb"); if(!fptr) return false; fread(&type, sizeof(short), 1, fptr); if(type != 0x4D42) { fclose(fptr); return false; } fseek(fptr, 10, SEEK_SET); fread(&offset, sizeof(long), 1, fptr); fseek(fptr, 4, SEEK_CUR); fread(&width, sizeof(long), 1, fptr); fread(&height, sizeof(long), 1, fptr); fseek(fptr, 2, SEEK_CUR); fread(&bitcount, sizeof(short), 1, fptr); if(bitcount != 24) { fclose(fptr); return false; } fseek(fptr, 4, SEEK_CUR); fread(&size, sizeof(long), 1, fptr); fseek(fptr,16,SEEK_CUR); pbits = new mxColor [ width * height ]; if(!pbits) { fclose(fptr); return false; } int i = 0; int x, y,q; for(y = height-1; y > -1; y--) { for(x = 0; x < width; x++) { q = x + y * width; pbits[q].b = fgetc(fptr); pbits[q].g = fgetc(fptr); pbits[q].r = fgetc(fptr); } for(i = 0; i < width % 4; i++) fgetc(fptr); } fclose(fptr); return true; } D3DCOLOR getPixel(int x, int y) { return pbits[x+y*width].toD3D(); } void SetColorKey(D3DCOLOR color_key) { this->color_key = color_key; color_key_active = true; } void RemoveColorKey() { color_key = 0xFF00FF; color_key_active = false; } void BltBuffer(int x, int y, int w, int h, mxHwnd *mx) { mx->paint.Lock(); int bx = 0, by = 0; if(x >= 0 && y >= 0) for(int i = x, bx = 0; i < w; i++, bx++) { for(int z = y, by = 0; z < h; z++, by++) { if(i < mx->w && z < mx->h ) { D3DCOLOR color = getPixel(bx,by); if(color_key_active == true && color != color_key) mx->paint.fast_sp(i,z,mx->paint.rect.Pitch, color); else if(color_key_active == false) mx->paint.fast_sp(i,z,mx->paint.rect.Pitch, color); } } } mx->paint.UnLock(); } void BltBuffer(int x, int y, mxHwnd *mx) { BltBuffer(x,y,x+width,y+height,mx); } void StretchBuffer(int x, int y, int nw, int nh, mxHwnd *mx) { mx->paint.Lock(); int bx = 0, by = 0; if(x >= 0 && y >= 0) for(int i = x, bx = 0; i < nw; i++, bx++) { for(int z = y, by = 0; z < nh; z++, by++) { if(i < mx->w && z < mx->h) { D3DCOLOR the_color = GetStretchPixel(bx,by,nw,nh); if(color_key_active == true && color_key != the_color) mx->paint.fast_sp(i,z,mx->paint.rect.Pitch, the_color); else if(color_key_active == false) mx->paint.fast_sp(i,z,mx->paint.rect.Pitch, GetStretchPixel(bx,by,nw,nh)); } } } mx->paint.UnLock(); } mxColor *GetBits() { return pbits; } mxColor *operator[](int pos) { return &pbits[pos]; } bool color_key_active; D3DCOLOR color_key; D3DCOLOR GetStretchPixel(int x, int y, int nw, int nh) { int xp = int((float)x * float(width) / (float)nw); int yp = int((float)y * float(height) / (float)nh); D3DCOLOR buffer_pos = pbits[yp*width+xp].toD3D(); return buffer_pos; } mxColor &getStretchPixel(int x, int y, int nw, int nh) { int xp = int((float)x * float(width) / (float)nw); int yp = int((float)y * float(height) / (float)nh); return pbits[yp*width+xp]; } // alpha blend this texture (assumes they are both the same size, and the back buffer is locked) void AlphaBlend(int x, int y,int w, int h, mxHwnd &mx, mxTexture &tex, float alpha) { static float fr,gr,br; static unsigned char r,g,b; static mxColor c,l; for(int i = 0; i < w; i++) for(int z = 0; z < h; z++) { c = GetPixel(i,z); l = tex.GetPixel(i,z); if((fr = ( alpha * c.r ) + (( 1- alpha) * l.r)) > 255) fr = 255; if((gr = ( alpha * c.g ) + (( 1- alpha) * l.g)) > 255) gr = 255; if((br = ( alpha * c.b ) + (( 1- alpha) * l.b)) > 255) br = 255; r = unsigned char(fr), g = unsigned char(gr), b = unsigned char(br); mx.paint.fast_sp(i+x,y+z,mx.paint.rect.Pitch,D3DCOLOR_XRGB(r,g,b)); } } void AlphaBlend(int x, int y, mxHwnd &mx, mxTexture &tex, float alpha) { AlphaBlend(x,y,tex.width,tex.height,mx,tex,alpha); } // add light through another texture ( assumes they are both the same size) and that the back buffer is locked void Light(int x, int y, int w, int h, mxHwnd &mx, mxTexture &tex, float scale) { static float fr,gr,br; static unsigned char r,g,b; static mxColor c,l; for(int i = 0; i < w; i++) for(int z = 0; z < h; z++) { c = GetPixel(i,z); l = tex.GetPixel(i,z); if((fr = c.r + (scale * l.r)) > 255) fr = 255; if((gr = c.g + (scale * l.g)) > 255) gr = 255; if((br = c.b + (scale * l.b)) > 255) br = 255; r = unsigned char(fr) , g = unsigned char (gr), b = unsigned char(br); mx.paint.fast_sp(i+x,y+z,mx.paint.rect.Pitch, D3DCOLOR_XRGB(r,g,b)); } } void Light(int x, int y, mxHwnd &mx, mxTexture &tex, float scale) { Light(x,y,tex.width,tex.height,mx,tex,scale); } mxColor *pbits; }; }