2 --- gtk/sdl.c 30 Jan 2004 18:43:34 -0000 1.13
3 +++ gtk/sdl.c 22 May 2004 15:51:51 -0000 1.14
9 +/* Draw a alpha square on lightmap. Topleft corner is at startx,starty.
10 + * values for topleft, topright, bottomleft,bottomright corners are knowns
11 + * This use bilinear interpolation for other points. Width and heights are given
12 + * for surrouding known values square. Interpolation is done in a small square whose
13 + * coordinates are given by start{x|y} and end{x|y}
14 + * dest{x|y} is top-left corner in destination map.
15 + * Tchize 22 May 2004
18 +void drawquarterlightmap_sdl(int tl, int tr, int bl, int br, /*colors*/
19 + int width, int height, /*color square size*/
20 + int startx, int starty, int endx, int endy, /*interpolation region*/
21 + int destx, int desty){ /*where in lightmap to save result*/
24 + for (x=startx;x<endx;x++){
25 + top= ((x*(tr-tl))/ width)+tl; /*linear interpolation for top color*/
26 + bottom= ((x*(br-bl))/ width)+bl; /*linear interpolation for bottom color*/
27 + for (y=starty;y<endy;y++){
28 + val=((y*(bottom-top))/height)+top; /*linear interpolation between top and bottom*/
33 + //printf("writing pel at %d,%d\n",destx+x,desty+y);
34 + putpixel(lightmap, destx+x-startx, desty+y-starty,
35 + SDL_MapRGBA(lightmap->format, 0, 0, 0, val));
40 /* Do the lighting on a per pixel basis.
41 * x and y are coordinates on the drawable map surfaces (but in terms of
42 * spaces, not pixels). mx and my are indexes into the
44 /* See note below about ALPHA_FUDGE - used to adjust lighting effects some */
46 #define ALPHA_FUDGE(x) (2*(x) / 3)
47 +#define GENDARK(x,y) ( (((x)&(y) & 1) == 1)?255:0 )
48 void do_sdl_per_pixel_lighting(int x, int y, int mx, int my)
52 if (x-1 < 0 || !the_map.cells[mx-1][my].have_darkness) dark4 = dark0;
53 else dark4 = the_map.cells[mx-1][my].darkness;
55 - /* If they are all the same, processing is easy */
56 - if (dark0 == dark1 && dark0 == dark2 && dark0 == dark3 && dark0 == dark4) {
57 + /*dark0=GENDARK(mx,my);
58 + dark1=GENDARK(mx,my-1);
59 + dark2=GENDARK(mx+1,my);
60 + dark3=GENDARK(mx,my+1);
61 + dark4=GENDARK(mx+1,my);*/
62 + /* If they are all the same, processing is easy
64 + * Note, the best lightining algorithm also uses diagonals
65 + * so we should check the diagonals are same too
66 + * We don't check for now, simply do all raw computation on best mode
67 + * Tchize 19 may 2004
69 + if (dark0 == dark1 && dark0 == dark2 && dark0 == dark3 && dark0 == dark4 && (use_config[CONFIG_LIGHTING] != CFG_LT_PIXEL_BEST)) {
70 dst.x = x * map_image_size;
71 dst.y = y * map_image_size;
72 dst.w = map_image_size;
74 dst.y= y * map_image_size;
75 SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
76 } else if (use_config[CONFIG_LIGHTING] == CFG_LT_PIXEL_BEST ) {
79 static int *darkx=NULL, *darky=NULL,darkx_allocated=0;
82 for (dx=0; dx<map_image_size; dx++)
83 for (dy=0; dy<map_image_size; dy++)
84 putpixel(lightmap, dx, dy, SDL_MapRGBA(lightmap->format, 0, 0, 0,(darkx[dx] + darky[dy])/2));
87 + /*we need additionnal surrounding infos*/
88 + int dark5, dark6, dark7, dark8;
89 + if ( (y-1 < 0) || (x+1 >= use_config[CONFIG_MAPWIDTH])
90 + || !the_map.cells[mx+1][my-1].have_darkness) dark5 = (dark1+dark2)>>1; /*(fast div 2)*/
91 + else dark5 = the_map.cells[mx+1][my-1].darkness;
93 + if ( (x+1 >= use_config[CONFIG_MAPWIDTH])
94 + || (y+1 >= use_config[CONFIG_MAPHEIGHT])
95 + || !the_map.cells[mx+1][my+1].have_darkness) dark6 = (dark2+dark3)>>1;
96 + else dark6 = the_map.cells[mx+1][my+1].darkness;
98 + if ( (y+1 >= use_config[CONFIG_MAPHEIGHT]) || (x-1 < 0)
99 + || !the_map.cells[mx-1][my+1].have_darkness) dark7 = (dark3+dark4)>>1;
100 + else dark7 = the_map.cells[mx-1][my+1].darkness;
102 + if ( (x-1 < 0) || (y-1 < 0)
103 + || !the_map.cells[mx-1][my-1].have_darkness) dark8 = (dark4+dark1)>>1;
104 + else dark8 = the_map.cells[mx-1][my-1].darkness;
105 + /*upper left lightmap quarter*/
106 + drawquarterlightmap_sdl(dark8, dark1, dark4, dark0, /*colors*/
107 + map_image_size, map_image_size, /*color square size*/
108 + map_image_half_size, map_image_half_size, map_image_size, map_image_size, /*interpolation region*/
109 + 0, 0); /*where in lightmap to save result*/
110 + /*upper right lightmap quarter*/
111 + drawquarterlightmap_sdl(dark1, dark5, dark0, dark2, /*colors*/
112 + map_image_size, map_image_size, /*color square size*/
113 + 0, map_image_half_size, map_image_half_size, map_image_size, /*interpolation region*/
114 + map_image_half_size, 0); /*where in lightmap to save result*/
115 + /*bottom left lightmap quarter*/
116 + drawquarterlightmap_sdl(dark4, dark0, dark7, dark3, /*colors*/
117 + map_image_size, map_image_size, /*color square size*/
118 + map_image_half_size, 0, map_image_size, map_image_half_size, /*interpolation region*/
119 + 0, map_image_half_size); /*where in lightmap to save result*/
120 + /*bottom right lightmap quarter*/
121 + drawquarterlightmap_sdl(dark0, dark2, dark3, dark6, /*colors*/
122 + map_image_size, map_image_size, /*color square size*/
123 + 0, 0, map_image_half_size, map_image_half_size, /*interpolation region*/
124 + map_image_half_size, map_image_half_size); /*where in lightmap to save result*/
126 dst.w= map_image_size;
127 dst.h= map_image_size;
128 dst.x= x * map_image_size;
129 dst.y= y * map_image_size;
130 - SDL_UnlockSurface( lightmap);
131 - SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
132 + SDL_UnlockSurface(lightmap);
133 + SDL_BlitSurface(lightmap, NULL, mapsurface, &dst);
136 /* Draw anything in adjacent squares that could smooth on given square
138 }/*while there's some smooth to do*/
141 +/* This function tells if a specifi square need to be redrawn
142 + * Reason for redrawing can be content change, smoothing change or
143 + * surrounding lightning change. Conditions depend on type of
144 + * lightning code used.
145 + * Tchize 22 May 2004
147 +int sdl_square_need_redraw(int mx, int my){
148 +#define SDL_LIGHT_CHANGED(_x_,_y_) ( ( ( (_x_)<0) || ( (_y_)<0) || ( (_x_)>=the_map.x) || ( (_y_)>=the_map.y) )?0: the_map.cells[_x_][_y_].need_update )
149 + if ( (the_map.cells[mx][my].need_update) || (the_map.cells[mx][my].need_resmooth))
152 + if (use_config[CONFIG_LIGHTING] == CFG_LT_PIXEL){
153 + /*The fast per pixel uses 4 additionnal datas which may have changed:*/
154 + /*we suppose need_redraw -> lightr may have change. in future maybe we could add a need_relight toggle*/
155 + if (SDL_LIGHT_CHANGED(mx-1,my) ||
156 + SDL_LIGHT_CHANGED(mx,my-1) ||
157 + SDL_LIGHT_CHANGED(mx+1,my) ||
158 + SDL_LIGHT_CHANGED(mx,my+1))
161 + if (use_config[CONFIG_LIGHTING] == CFG_LT_PIXEL_BEST){
162 + if (SDL_LIGHT_CHANGED(mx-1,my) ||
163 + SDL_LIGHT_CHANGED(mx,my-1) ||
164 + SDL_LIGHT_CHANGED(mx+1,my) ||
165 + SDL_LIGHT_CHANGED(mx,my+1) ||
166 + SDL_LIGHT_CHANGED(mx-1,my+1) ||
167 + SDL_LIGHT_CHANGED(mx-1,my-1) ||
168 + SDL_LIGHT_CHANGED(mx+1,my-1) ||
169 + SDL_LIGHT_CHANGED(mx+1,my+1) )
172 + return 0; /*no need to redraw :)*/
175 /* This generates a map in SDL mode.
177 * I had to totally change the logic on how we do this in SDL mode -
180 struct timeval tv1, tv2,tv3;
181 long elapsed1, elapsed2;
184 + static int last_mapwidth=0;
185 + static int last_mapheight=0;
186 + static uint8 *redrawbitmap=NULL;
189 gettimeofday(&tv1, NULL);
191 + /* In per pixel lightning code, some square may have to be
192 + * redrawn just because a surrounding square did change
193 + * However, informations on changed square do get toggle
194 + * during the redraw process. To keep track of which
195 + * squares really need redraw (instead of redrawing eveything in
196 + * per pixel lightning case), we need to save this info in a array
197 + * Tchize, 22 May 2004
199 + if ( (use_config[CONFIG_MAPWIDTH] != last_mapwidth) ||
200 + (use_config[CONFIG_MAPHEIGHT] != last_mapheight) ){
201 + /* reallocate array */
202 + last_mapwidth=use_config[CONFIG_MAPWIDTH];
203 + last_mapheight=use_config[CONFIG_MAPHEIGHT];
204 + redrawbitmap=(uint8*)malloc(sizeof(uint8)*last_mapwidth*last_mapheight);
206 + if (redrawbitmap==NULL){
207 + LOG(LOG_ERROR,"sdl::sdl_gen_map",
208 + "The redraw bitmap is NULL. Not enough memory? (width:%d,height:%d)",
209 + last_mapwidth,last_mapheight);
210 + return; /*without this bitmap, no drawing possible*/
214 #if !ALTERNATE_MAP_REDRAW
215 if (map_did_scroll) {
219 for( x= 0; x<use_config[CONFIG_MAPWIDTH]; x++) {
220 + for(y = 0; y<use_config[CONFIG_MAPHEIGHT]; y++) {
221 + redrawbitmap[x+y*last_mapwidth]=(uint8)sdl_square_need_redraw(x+pl_pos.x,y+pl_pos.y);
224 + for( x= 0; x<use_config[CONFIG_MAPWIDTH]; x++) {
225 for(y = 0; y<use_config[CONFIG_MAPHEIGHT]; y++) {
226 /* mx,my represent the spaces on the 'virtual' map (ie, the_map structure).
227 * x and y (from the for loop) represent the visable screen.
231 /* Don't need to touch this space */
232 - if (!redraw && !the_map.cells[mx][my].need_update && !the_map.cells[mx][my].need_resmooth)
235 + if (!redrawbitmap[x+y*last_mapwidth])
237 /* First, we need to black out this space. */
238 dst.x = x * map_image_size; dst.y = y* map_image_size;
239 dst.w = map_image_size; dst.h = map_image_size;