]>
Commit | Line | Data |
---|---|---|
9752ef44 JK |
1 | diff -u -r1.13 -r1.14 |
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 | |
4 | @@ -308,6 +308,38 @@ | |
5 | } | |
6 | } | |
7 | ||
8 | + | |
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 | |
16 | + */ | |
17 | + | |
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*/ | |
22 | + int x,y; | |
23 | + int top,bottom,val; | |
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*/ | |
29 | + if (val>255) | |
30 | + val=255; | |
31 | + if (val<0) | |
32 | + val=0; | |
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)); | |
36 | + } | |
37 | + } | |
38 | +} | |
39 | + | |
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 | |
43 | @@ -338,6 +370,7 @@ | |
44 | /* See note below about ALPHA_FUDGE - used to adjust lighting effects some */ | |
45 | ||
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) | |
49 | { | |
50 | ||
51 | @@ -361,8 +394,19 @@ | |
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; | |
54 | ||
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 | |
63 | + * | |
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 | |
68 | + */ | |
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; | |
73 | @@ -483,6 +527,7 @@ | |
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 ) { | |
77 | +#if 0 | |
78 | int dx,dy; | |
79 | static int *darkx=NULL, *darky=NULL,darkx_allocated=0; | |
80 | ||
81 | @@ -512,13 +557,52 @@ | |
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)); | |
85 | - | |
86 | +#else | |
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; | |
92 | + | |
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; | |
97 | + | |
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; | |
101 | + | |
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*/ | |
125 | +#endif | |
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); | |
134 | } | |
135 | } | |
136 | /* Draw anything in adjacent squares that could smooth on given square | |
137 | @@ -656,6 +740,40 @@ | |
138 | }/*while there's some smooth to do*/ | |
139 | } | |
140 | ||
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 | |
146 | + */ | |
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)) | |
150 | + return 1; | |
151 | + | |
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)) | |
159 | + return 1; | |
160 | + } | |
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) ) | |
170 | + return 1; | |
171 | + } | |
172 | + return 0; /*no need to redraw :)*/ | |
173 | +} | |
174 | + | |
175 | /* This generates a map in SDL mode. | |
176 | * | |
177 | * I had to totally change the logic on how we do this in SDL mode - | |
178 | @@ -684,9 +802,36 @@ | |
179 | SDL_Rect dst, src; | |
180 | struct timeval tv1, tv2,tv3; | |
181 | long elapsed1, elapsed2; | |
182 | - | |
183 | + | |
184 | + static int last_mapwidth=0; | |
185 | + static int last_mapheight=0; | |
186 | + static uint8 *redrawbitmap=NULL; | |
187 | + | |
188 | if (time_map_redraw) | |
189 | gettimeofday(&tv1, NULL); | |
190 | + | |
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 | |
198 | + */ | |
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); | |
205 | + } | |
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*/ | |
211 | + } | |
212 | + | |
213 | ||
214 | #if !ALTERNATE_MAP_REDRAW | |
215 | if (map_did_scroll) { | |
216 | @@ -696,6 +841,11 @@ | |
217 | #endif | |
218 | ||
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); | |
222 | + } | |
223 | + } | |
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. | |
228 | @@ -704,9 +854,8 @@ | |
229 | my = y + pl_pos.y; | |
230 | ||
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) | |
233 | - continue; | |
234 | - | |
235 | + if (!redrawbitmap[x+y*last_mapwidth]) | |
236 | + continue; | |
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; |