2 "$Id: sdl.c 9190 2008-06-01 08:53:05Z anmaster $";
31 #include <SDL_image.h>
36 #include <gdk/gdkkeysyms.h>
43 SDL_Surface* mapsurface;
44 static SDL_Surface* lightmap;
45 static SDL_Surface* fogmap;
58 #include <SDL_image.h>
61 static void do_SDL_error(
const char *SDL_function,
const char *file,
int line)
64 file, line, SDL_GetError());
76 static void putpixel(SDL_Surface *surface,
int x,
int y, Uint32 pixel)
78 int bpp = surface->format->BytesPerPixel;
80 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
92 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
93 p[0] = (pixel >> 16) & 0xff;
94 p[1] = (pixel >> 8) & 0xff;
98 p[1] = (pixel >> 8) & 0xff;
99 p[2] = (pixel >> 16) & 0xff;
104 *(Uint32 *)p = pixel;
109 static void overlay_grid(
int re_init,
int ax,
int ay)
112 static SDL_Surface* grid_overlay;
114 static int first_pass;
120 SDL_PixelFormat* fmt;
129 SDL_FreeSurface( grid_overlay);
135 if( grid_overlay == NULL)
137 grid_overlay= SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA,
140 mapsurface->format->BitsPerPixel,
141 mapsurface->format->Rmask,
142 mapsurface->format->Gmask,
143 mapsurface->format->Bmask,
144 mapsurface->format->Amask);
145 if( grid_overlay == NULL)
146 do_SDL_error(
"CreateRGBSurface", __FILE__, __LINE__);
148 grid_overlay= SDL_DisplayFormatAlpha( grid_overlay);
164 fmt= grid_overlay->format;
170 pixel= (Uint32*)grid_overlay->pixels+y*grid_overlay->pitch/4+x;
172 if( x == 0 || y == 0 ||
176 *pixel= SDL_MapRGBA( fmt, 255, 0, 0, SDL_ALPHA_OPAQUE);
180 *pixel= SDL_MapRGBA( fmt, 0, 0, 0, SDL_ALPHA_TRANSPARENT);
194 SDL_BlitSurface( grid_overlay, NULL, mapsurface, &dst);
205 SDL_BlitSurface( grid_overlay, &dst, mapsurface, &dst);
218 void init_SDL( GtkWidget* sdl_window,
int just_lightmap)
221 char SDL_windowhack[32];
223 if( just_lightmap == 0) {
224 g_assert( sdl_window != NULL);
225 if( SDL_WasInit( SDL_INIT_VIDEO) != 0) {
227 SDL_FreeSurface( lightmap);
229 SDL_FreeSurface( mapsurface);
236 sprintf( SDL_windowhack,
"SDL_WINDOWID=%ld",
237 GDK_WINDOW_XWINDOW(sdl_window->window) );
238 putenv( SDL_windowhack);
240 if( SDL_Init( SDL_INIT_VIDEO) < 0)
242 LOG(
LOG_CRITICAL,
"gtk::init_SDL",
"Could not initialize SDL: %s", SDL_GetError());
247 SDL_HWSURFACE|SDL_DOUBLEBUF);
249 if( mapsurface == NULL)
251 do_SDL_error(
"SetVideoMode", __FILE__, __LINE__);
255 SDL_FreeSurface( fogmap);
257 fogmap= SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA,
map_image_size,
259 mapsurface->format->BitsPerPixel,
260 mapsurface->format->Rmask,
261 mapsurface->format->Gmask,
262 mapsurface->format->Bmask,
263 mapsurface->format->Amask);
267 do_SDL_error(
"SDL_CreateRGBSurface", __FILE__, __LINE__);
274 if( SDL_SetAlpha( fogmap, SDL_SRCALPHA|SDL_RLEACCEL, 128) < 0)
276 do_SDL_error(
"SDL_SetAlpha", __FILE__, __LINE__);
280 if( just_lightmap != 0 && lightmap)
281 SDL_FreeSurface( lightmap);
283 lightmap= SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA,
map_image_size,
285 mapsurface->format->BitsPerPixel,
286 mapsurface->format->Rmask,
287 mapsurface->format->Gmask,
288 mapsurface->format->Bmask,
289 mapsurface->format->Amask);
290 if( lightmap == NULL)
292 do_SDL_error(
"SDL_CreateRGBSurface", __FILE__, __LINE__);
299 lightmap= SDL_DisplayFormatAlpha( lightmap);
300 if( lightmap == NULL)
302 do_SDL_error(
"DisplayFormatAlpha", __FILE__, __LINE__);
308 overlay_grid(
TRUE, 0, 0);
324 int startx,
int starty,
int endx,
int endy,
325 int destx,
int desty){
328 for (x=startx;x<endx;x++){
329 top= ((x*(tr-tl))/
width)+tl;
330 bottom= ((x*(br-bl))/
width)+bl;
331 for (y=starty;y<endy;y++){
332 val=((y*(bottom-top))/
height)+top;
338 putpixel(lightmap, destx+x-startx, desty+y-starty,
339 SDL_MapRGBA(lightmap->format, 0, 0, 0, val));
373 #define ALPHA_FUDGE(x) (2*(x) / 3)
374 static void do_sdl_per_pixel_lighting(
int x,
int y,
int mx,
int my)
410 SDL_FillRect(mapsurface,&dst, SDL_MapRGB(mapsurface->format, 0, 0, 0));
412 SDL_FillRect(lightmap,NULL, SDL_MapRGBA(lightmap->format, 0, 0, 0,
the_map.
cells[mx][my].
darkness));
413 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
437 if (dark1 == dark0) {
446 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0, ALPHA_FUDGE(dark0)));
455 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0,
456 ALPHA_FUDGE((map_image_half_size - i) * dark1 + i * dark0)/map_image_half_size));
462 if (dark3 == dark0) {
467 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0, ALPHA_FUDGE(dark0)));
476 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0,
477 ALPHA_FUDGE(dark0*(map_image_size-i) + dark3*(i-map_image_half_size)) / map_image_half_size));
485 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
487 if (dark4 == dark0) {
492 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0, ALPHA_FUDGE(dark0)));
500 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0,
501 ALPHA_FUDGE(dark4*(map_image_half_size-i) + dark0*i) / map_image_half_size));
503 if (dark2 == dark0) {
508 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0, ALPHA_FUDGE(dark0)));
517 SDL_FillRect(lightmap, &dst, SDL_MapRGBA(lightmap->format, 0, 0, 0,
518 ALPHA_FUDGE(dark0*(map_image_size-i) + dark2*(i-map_image_half_size)) / map_image_half_size));
522 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
526 static int *darkx=NULL, *darky=NULL,darkx_allocated=0;
533 if (map_image_size > darkx_allocated) {
534 darkx = realloc(darkx, map_image_size *
sizeof(
int));
535 darky = realloc(darky, map_image_size *
sizeof(
int));
542 darkx[dx] = (dark0*(map_image_size-dx) + dark2*(dx-map_image_half_size)) /
map_image_half_size;
547 darky[dy] = (dark0*(map_image_size-dy) + dark3*(dy-map_image_half_size)) /
map_image_half_size;
549 SDL_LockSurface( lightmap);
553 putpixel(lightmap, dx, dy, SDL_MapRGBA(lightmap->format, 0, 0, 0,(darkx[dx] + darky[dy])/2));
556 int dark5, dark6, dark7, dark8;
570 if ( (x-1 < 0) || (y-1 < 0)
575 map_image_size, map_image_size,
576 map_image_half_size, map_image_half_size, map_image_size, map_image_size,
580 map_image_size, map_image_size,
581 0, map_image_half_size, map_image_half_size, map_image_size,
582 map_image_half_size, 0);
585 map_image_size, map_image_size,
586 map_image_half_size, 0, map_image_size, map_image_half_size,
587 0, map_image_half_size);
590 map_image_size, map_image_size,
591 0, 0, map_image_half_size, map_image_half_size,
592 map_image_half_size, map_image_half_size);
598 SDL_UnlockSurface(lightmap);
599 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
608 static void drawsmooth_sdl (
int mx,
int my,
int layer,SDL_Rect dst){
609 static int dx[8]={0,1,1,1,0,-1,-1,-1};
610 static int dy[8]={-1,-1,0,1,1,1,0,-1};
611 static int bweights[8]={2,0,4,0,8,0,1,0};
612 static int cweights[8]={0,2,0,4,0,8,0,1};
613 static int bc_exclude[8]={
623 int partdone[8]={0,0,0,0,0,0,0,0};
626 int i,lowest,weight,weightC;
631 for (i=0;i<=layer;i++)
664 if ( (slevels[i]>0) && (!partdone[i]) &&
665 ((lowest<0) || (slevels[i]<slevels[lowest]))
684 if ( (slevels[i]==slevels[lowest]) &&
685 (sfaces[i]==sfaces[lowest])){
687 weight=weight+bweights[i];
688 weightC&=~bc_exclude[i];
691 weightC&=~cweights[i];
696 if (sfaces[lowest]<=0)
698 smoothface=sfaces[lowest];
711 src.x=map_image_size*weight;
715 &src, mapsurface, &dst))
716 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
719 &src, mapsurface, &dst))
720 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
724 src.x=map_image_size*weightC;
728 &src, mapsurface, &dst))
729 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
732 &src, mapsurface, &dst))
733 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
745 static int sdl_square_need_redraw(
int mx,
int my){
746 #define SDL_LIGHT_CHANGED(_x_,_y_) (!mapdata_is_inside((_x_), (_y_)) ? 0 : the_map.cells[_x_][_y_].need_update)
753 if (SDL_LIGHT_CHANGED(mx-1,my) ||
754 SDL_LIGHT_CHANGED(mx,my-1) ||
755 SDL_LIGHT_CHANGED(mx+1,my) ||
756 SDL_LIGHT_CHANGED(mx,my+1))
760 if (SDL_LIGHT_CHANGED(mx-1,my) ||
761 SDL_LIGHT_CHANGED(mx,my-1) ||
762 SDL_LIGHT_CHANGED(mx+1,my) ||
763 SDL_LIGHT_CHANGED(mx,my+1) ||
764 SDL_LIGHT_CHANGED(mx-1,my+1) ||
765 SDL_LIGHT_CHANGED(mx-1,my-1) ||
766 SDL_LIGHT_CHANGED(mx+1,my-1) ||
767 SDL_LIGHT_CHANGED(mx+1,my+1) )
783 SDL_FillRect(mapsurface, &dst, SDL_MapRGB(mapsurface->format, 0, 0, 0));
789 for (layer=0; layer<
MAXLAYERS; layer++) {
806 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
809 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
819 drawsmooth_sdl (mx,my,layer,dst);
830 int dx, dy, sourcex, sourcey, offx, offy;
833 offx = dx?(map_image_size -dx):0;
836 sourcex = sx * map_image_size - offx ;
843 offy = dy?(map_image_size -dy):0;
846 sourcey = sy * map_image_size - offy;
854 src.w = map_image_size - offx;
855 src.h = map_image_size - offy;
856 dst.x = ax*map_image_size + offx;
857 dst.y = ay*map_image_size + offy;
861 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
864 do_SDL_error(
"BlitSurface", __FILE__, __LINE__);
881 SDL_FillRect(mapsurface,&dst, SDL_MapRGB(mapsurface->format, 0, 0, 0));
884 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
887 do_sdl_per_pixel_lighting(ax, ay, mx, my);
916 struct timeval tv1, tv2,tv3;
917 long elapsed1, elapsed2;
919 static int last_mapwidth=0;
920 static int last_mapheight=0;
921 static uint8 *redrawbitmap=NULL;
924 gettimeofday(&tv1, NULL);
934 if ( (
use_config[CONFIG_MAPWIDTH] != last_mapwidth) ||
935 (
use_config[CONFIG_MAPHEIGHT] != last_mapheight) ){
939 redrawbitmap=(
uint8*)malloc(
sizeof(
uint8)*last_mapwidth*last_mapheight);
941 if (redrawbitmap==NULL){
943 "The redraw bitmap is NULL. Not enough memory? (width:%d,height:%d)",
944 last_mapwidth,last_mapheight);
960 if (redraw || redrawbitmap[x+y*last_mapwidth]) {
969 gettimeofday(&tv2, NULL);
971 SDL_Flip(mapsurface);
974 gettimeofday(&tv3, NULL);
975 elapsed1 = (tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec);
976 elapsed2 = (tv3.tv_sec - tv2.tv_sec)*1000000 + (tv3.tv_usec - tv2.tv_usec);
980 if ((elapsed1 + elapsed2)>10000)
981 LOG(
LOG_INFO,
"gtk::sdl_gen_map",
"gen took %7ld, flip took %7ld, total = %7ld",
982 elapsed1, elapsed2, elapsed1 + elapsed2);
992 SDL_LockSurface( mapsurface);
995 memmove( mapsurface->pixels + offset, mapsurface->pixels,
996 mapsurface->pitch * (mapsurface->h + dy*map_image_size) );
1000 memmove( mapsurface->pixels, mapsurface->pixels + offset,
1001 mapsurface->pitch * (mapsurface->h - dy*map_image_size) );
1006 for( y= 0; y < mapsurface->h; y++) {
1008 char* start_of_row= mapsurface->pixels + mapsurface->pitch * y;
1009 int offset= ( mapsurface->format->BytesPerPixel * map_image_size * -dx);
1010 memmove( start_of_row + offset, start_of_row,
1011 mapsurface->pitch - offset);
1014 char* start_of_row= mapsurface->pixels + mapsurface->pitch * y;
1015 int offset= ( mapsurface->format->BytesPerPixel * map_image_size * dx);
1016 memmove( start_of_row, start_of_row + offset,
1017 mapsurface->pitch - offset);
1021 SDL_UnlockSurface( mapsurface);
#define CAN_SMOOTH(__SQUARE, __LEVEL)
void init_SDL(GtkWidget *sdl_window, int just_lightmap)
#define CFG_LT_PIXEL_BEST
PixmapInfo * pixmaps[MAXPIXMAPNUM]
void LOG(LogLevel level, const char *origin, const char *format,...)
int sdl_mapscroll(int dx, int dy)
const char *const rcsid_gtk_sdl_c
static void display_mapcell(int ax, int ay, int mx, int my)
sint16 use_config[CONFIG_NUMS]
sint16 mapdata_face(int x, int y, int layer)
void drawquarterlightmap_sdl(int tl, int tr, int bl, int br, int width, int height, int startx, int starty, int endx, int endy, int destx, int desty)
sint16 mapdata_bigface(int x, int y, int layer, int *ww, int *hh)
struct MapCellLayer heads[MAXLAYERS]
void sdl_gen_map(int redraw)