Files
ia2005/InterfaceCpp/sdlcommon.cpp
2024-11-12 17:41:10 +01:00

239 lines
5.8 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <math.h>
#include "sdlcommon.h"
bool inCarArea(SDL_Surface *screen, int x, int y)
{
if(x<0 || y<0 || x>screen->w || y>screen->h) return 0;
if(x<320 && y<100) return 0;
//DrawLine(screen,0,100,320,100,0,0,128);
return 1;
}
void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b)
{
Uint8 *ubuff8;
Uint16 *ubuff16;
Uint32 *ubuff32;
Uint32 color;
char c1, c2, c3;
if(x >= screen->w || x < 0 || y >= screen->h || y <0 ) return;
if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen) < 0)
return;
}
color = SDL_MapRGB( screen->format, r, g, b );
switch(screen->format->BytesPerPixel)
{
case 1:
ubuff8 = (Uint8*) screen->pixels;
ubuff8 += (y * screen->pitch) + x;
*ubuff8 = (Uint8) color;
break;
case 2:
ubuff8 = (Uint8*) screen->pixels;
ubuff8 += (y * screen->pitch) + (x*2);
ubuff16 = (Uint16*) ubuff8;
*ubuff16 = (Uint16) color;
break;
case 3:
ubuff8 = (Uint8*) screen->pixels;
ubuff8 += (y * screen->pitch) + (x*3);
if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
c1 = (color & 0xFF0000) >> 16;
c2 = (color & 0x00FF00) >> 8;
c3 = (color & 0x0000FF);
}
else {
c3 = (color & 0xFF0000) >> 16;
c2 = (color & 0x00FF00) >> 8;
c1 = (color & 0x0000FF);
}
ubuff8[0] = c3;
ubuff8[1] = c2;
ubuff8[2] = c1;
break;
case 4:
ubuff8 = (Uint8*) screen->pixels;
ubuff8 += (y*screen->pitch) + (x*4);
ubuff32 = (Uint32*)ubuff8;
*ubuff32 = color;
break;
default:
fprintf(stderr, "Error: Unknown bitdepth!\n");
}
if(SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}
}
int getpixel(SDL_Surface *screen, int x, int y)
{
int bpp = screen->format->BytesPerPixel;
Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * bpp;
switch(bpp)
{
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0;
}
}
void interpole(SDL_Surface* src, SDL_Surface* dst, Uint32 nulcol)
{
/* Interpolation */
Uint32 ipol;
for(int i=1;i< (src->w-1) ;i++)
for(int j=1;j< (src->h-1);j++)
{
if((ipol=getpixel(src,i,j))==nulcol)
{
Uint32 ir=0,ig=0,ib=0;
int tot=0;
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i,j-2))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i,j+1))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i-2,j))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if((ipol=getpixel(src,i+2,j))!=NULLCOL){
ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
tot++;
}
if(tot>3)
{
ir/=tot;
ig/=tot;
ib/=tot;
//printf("interpol pixel %d,%d, with %d,%d,%d (%d)\n",i,j,ir,ig,ib,tot);
setpixel(dst,i,j,(Uint8)ir,(Uint8)ig,(Uint8)ib);
//setpixel(dst,i,j,255,0,0);
}
// else pixel à interpolé entouré de rien ...
}
else {
setpixel(dst,i,j,(Uint8)(ipol>>16),(Uint8)(ipol>>8),(Uint8)(ipol));
//setpixel(dst,i,j,0,255,0);
}
}
}
void DrawLine(SDL_Surface* screen, int x1, int y1, int x2, int y2, char r, char g, char b)
{
double dx,dy,x,y;
int step,i;
if(abs(x2-x1)>abs(y2-y1)) step=abs(x2-x1);
else step=abs(y2-y1);
dx=(x2-x1);
dy=(y2-y1);
dx/=step;
dy/=step;
x=x1;
y=y1;
for(i=0;i<step;i++)
{
x=x+dx;
y=y+dy;
setpixel(screen,(int)x,(int)y,r,g,b);
}
}
void rotatesurface(SDL_Surface *src, SDL_Surface *dst, int anginc)
{
Uint32 pix,x,y;
double angle,ba,ca,norm;
Uint8 r,g,b;
SDL_Surface *tmp;
SDL_Rect rec;
rec.h=src->h;
rec.w=src->w;
rec.x=0;
rec.y=0;
tmp=SDL_CreateRGBSurface(SDL_HWSURFACE, src->w, src->h, 32, 0,0,0,0);
SDL_FillRect(tmp,&rec, SDL_MapRGB(tmp->format,NULLCOLR,NULLCOLG,NULLCOLB/**/));
SDL_FillRect(dst,&rec, SDL_MapRGB(tmp->format,NULLCOLR,NULLCOLG,NULLCOLB/**/));
for(int i=0;i<src->w;i++)
for(int j=0;j<src->h;j++)
{
pix=getpixel(src,i,j);
r=pix>>16; // couleur R
g=pix>>8; // couleur G
b=pix; // couleur B
ba=(src->w/2)-i; // base
ca=(src->h/2)-j; // cote adjascent
norm=sqrt(ba*ba+ca*ca); // norme
angle=atan(ca/ba); // angle
if(i>(src->w)/2) angle+=(PI);
angle+=(anginc*PI/180); // angle tourné
x=(int)round((src->w/2)-(norm*cos(angle)));
y=(int)round((src->h/2)-(norm*sin(angle)));
setpixel(tmp, x,y, r,g,b);
}
pix=getpixel(src,(src->w/2),(src->h/2));
setpixel(tmp, (src->w/2),(src->h/2), pix>>16,pix>>8,pix);
//SDL_BlitSurface(tmp , NULL, dst, NULL);
interpole(tmp,dst, NULLCOL);
}