Code: Select all
#include <SDL/SDL.h>
#include <math.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void SDL_Rotate(SDL_Surface *surface, SDL_Rect *rect, float angle, int x, int y) {
SDL_LockSurface(surface);
int bpp = surface->format->BytesPerPixel;
int white = SDL_MapRGB(surface->format,0xff,0xff,0xff);
char* pixels = (char*)malloc(surface->w*surface->h*bpp);
for (int i = surface->w*surface->h; i >= 0; --i) {
char* c = pixels+i*bpp;
memcpy(c,&white,bpp);
}
for(int sx = surface->w; sx >= 0; --sx) {
for (int sy = surface->h; sy >= 0; --sy) {
if (sx >= rect->x && sx < (rect->x+rect->w) && sy >= rect->y && sy < (rect->y+rect->h)) { //Point in surface is part of rect
float curangle;
bool xshift = (abs(sx) > abs(x))?1:0;
bool yshift = (abs(sy) > abs(y))?0:1;
if (sx-x == 0) {curangle = (abs(sy) > abs(y))?270:90;}
else {curangle = atan((float)(sy-y+yshift)/(float)(sx-x+xshift)) * 180/3.14159;}
if (abs(sx-x) != sx-x) { //Correct angle, since atan() only returns [-pi/2,pi/2]
curangle=180.0-curangle;
}
if (fabs(curangle) != curangle) {curangle+=360;}
float l = sqrt(pow(sx-x,2)+pow(sy-y,2));
char* p = (char*)surface->pixels+sx*bpp+sy*surface->pitch;
char* q = (char*)pixels+(int)((cos((angle+curangle)*3.14159/180)*l)+x)*bpp+(int)((sin((angle+curangle)*3.14159/180)*l)+y)*surface->pitch;
memcpy(q,p,bpp);
if(memcmp(q+bpp,&white,bpp) == 0) {
memcpy(q+bpp,q,bpp); //To effectively cover without many/any holes
}
}
}
}
memcpy(surface->pixels,pixels,surface->w*surface->h*bpp);
SDL_UnlockSurface(surface);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *videoSurface = SDL_SetVideoMode(640,480,16,0);
int white = SDL_MapRGB(videoSurface->format,0xff,0xff,0xff);
int black = SDL_MapRGB(videoSurface->format,0x00,0x00,0x00);
SDL_FillRect(videoSurface,NULL,white);
SDL_Rect* rect = new SDL_Rect();
rect->h = 120;
rect->w = 100;
rect->x = videoSurface->w/2-60;
rect->y = videoSurface->h/2-50;
SDL_FillRect(videoSurface,rect,black);
SDL_LockSurface(videoSurface);
char* original_pixels = (char*)malloc(videoSurface->w*videoSurface->h*videoSurface->format->BytesPerPixel);
memcpy(original_pixels,videoSurface->pixels,videoSurface->w*videoSurface->h*videoSurface->format->BytesPerPixel);
SDL_UnlockSurface(videoSurface);
SDL_UpdateRect(videoSurface,0,0,videoSurface->w,videoSurface->h);
atexit(SDL_Quit);
sleep(1);
for(int t = 15; t < 360; t+=15) {
SDL_Rotate(videoSurface,rect,t,rect->x+rect->w/2,rect->y+rect->h/2);
SDL_UpdateRect(videoSurface,0,0,videoSurface->w,videoSurface->h);
sleep(1);
SDL_LockSurface(videoSurface);
memcpy(videoSurface->pixels,original_pixels,videoSurface->h*videoSurface->w*videoSurface->format->BytesPerPixel);
SDL_UnlockSurface(videoSurface);
}
}
I have found that function that *should* serve my needs, but I was wondering if anyone else had a function they were willing to lend? or could help me fix the above function so it works properly? I am building a tile map editor, and the user should be able to rotate specific tiles, and add them into an overall tile surface... I haven't done any surface merging yet D: