// KK20Rotate.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
typedef union {
unsigned int pixel;
struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
} RGSSRGBA;
typedef struct {
DWORD flags;
DWORD klass;
void(*dmark) (void*);
void(*dfree) (void*);
BYTE *data; //B = 0, G = 1, R = 2, A = 3
} RGSSCOLOR;
typedef struct {
DWORD unk1;
DWORD unk2;
BITMAPINFOHEADER *infoheader;
RGSSRGBA *firstRow;
RGSSRGBA *lastRow;
} RGSSBMINFO;
typedef struct {
DWORD unk1;
DWORD unk2;
RGSSBMINFO *bminfo;
} BITMAPSTRUCT;
typedef struct {
DWORD flags;
DWORD klass;
void(*dmark) (void*);
void(*dfree) (void*);
BITMAPSTRUCT *bm;
} RGSSBITMAP;
extern "C" _declspec (dllexport) bool RotateRGSSBmp(long bmp, float * matrix)
{
RGSSBMINFO *bitmap = ((RGSSBITMAP*)(bmp << 1))->bm->bminfo;
long width, height;
RGSSRGBA *row;
RGSSRGBA *rowcopy;
long x, y;
float nx, ny;
float cx, cy;
unsigned char red, green, blue, alpha;
float transx, transy, transw;
if (!bitmap)
return false;
width = bitmap->infoheader->biWidth;
height = bitmap->infoheader->biHeight;
cx = (float)width / 2 + 0.0001;
cy = (float)height / 2 + 0.0001;
rowcopy = new RGSSRGBA[width*height];
row = bitmap->lastRow;
memcpy(rowcopy, row, width*height * 4);
RGSSRGBA *sourcepos;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
nx = x - cx;
ny = y - cy;
transx = (float)(matrix[0] * nx + matrix[1] * ny + matrix[2]);
transy = (float)(matrix[3] * nx + matrix[4] * ny + matrix[5]);
transw = (float)(matrix[6] * nx + matrix[7] * ny + matrix[8]);
// Dividing by zero is bad
if (transw == 0)
transw = (float)0.001;
transx = (transx + cx) / transw;
transy = (transy + cy) / transw;
if (transx < 0 || transx > width || transy < 0 || transy > height)
{
red = 0;
green = 0;
blue = 0;
alpha = 0;
}
else
{
sourcepos = rowcopy + (int)transx + ((int)transy * width);
red = sourcepos->red;
green = sourcepos->green;
blue = sourcepos->blue;
alpha = sourcepos->alpha;
}
row->red = red;
row->green = green;
row->blue = blue;
row->alpha = alpha;
row++;
}
}
delete[]rowcopy;
return true;
}