00001
00005 #include <allegro.h>
00006
00007 #include "alleggl.h"
00008 #include "allglint.h"
00009
00010
00011 static int best, best_score;
00012
00013
00014 #define target allegro_gl_display_info
00015 #define req __allegro_gl_required_settings
00016 #define sug __allegro_gl_suggested_settings
00017
00018
00019
00020
00021
00022
00023
00024 void __allegro_gl_fill_in_info() {
00025
00026 int all_components = AGL_RED_DEPTH | AGL_GREEN_DEPTH | AGL_BLUE_DEPTH
00027 | AGL_ALPHA_DEPTH;
00028
00029
00030 if ((((req | sug) & AGL_COLOR_DEPTH) == 0)
00031 && (((req | sug) & all_components) == all_components)) {
00032
00033 target.colour_depth = target.pixel_size.rgba.r
00034 + target.pixel_size.rgba.g
00035 + target.pixel_size.rgba.b
00036 + target.pixel_size.rgba.a;
00037
00038
00039 target.colour_depth = (target.colour_depth + 7) / 8;
00040 }
00041
00042 else if ((req | sug) & all_components) {
00043
00044 int avg = ((req | sug) & AGL_RED_DEPTH ? target.pixel_size.rgba.r: 0)
00045 + ((req | sug) & AGL_GREEN_DEPTH ? target.pixel_size.rgba.g: 0)
00046 + ((req | sug) & AGL_BLUE_DEPTH ? target.pixel_size.rgba.b: 0)
00047 + ((req | sug) & AGL_ALPHA_DEPTH ? target.pixel_size.rgba.a: 0);
00048
00049 int num = ((req | sug) & AGL_RED_DEPTH ? 1 : 0)
00050 + ((req | sug) & AGL_GREEN_DEPTH ? 1 : 0)
00051 + ((req | sug) & AGL_BLUE_DEPTH ? 1 : 0)
00052 + ((req | sug) & AGL_ALPHA_DEPTH ? 1 : 0);
00053
00054 avg /= (num ? num : 1);
00055
00056 if (((req | sug) & AGL_RED_DEPTH )== 0) {
00057 sug |= AGL_RED_DEPTH;
00058 target.pixel_size.rgba.r = avg;
00059 }
00060 if (((req | sug) & AGL_GREEN_DEPTH) == 0) {
00061 sug |= AGL_GREEN_DEPTH;
00062 target.pixel_size.rgba.g = avg;
00063 }
00064 if (((req | sug) & AGL_BLUE_DEPTH) == 0) {
00065 sug |= AGL_BLUE_DEPTH;
00066 target.pixel_size.rgba.b = avg;
00067 }
00068 if (((req | sug) & AGL_ALPHA_DEPTH) == 0) {
00069 sug |= AGL_ALPHA_DEPTH;
00070 target.pixel_size.rgba.a = avg;
00071 }
00072
00073
00074 if (((req | sug) & AGL_COLOR_DEPTH) == 0) {
00075 __allegro_gl_fill_in_info();
00076 }
00077 }
00078
00079
00080
00081
00082 if ((((req | sug) & AGL_COLOR_DEPTH) == 0) && (target.colour_depth == 0)) {
00083 BITMAP *temp = create_bitmap(1, 1);
00084 if (temp) {
00085 allegro_gl_set(AGL_COLOR_DEPTH, bitmap_color_depth(temp));
00086 allegro_gl_set(AGL_REQUIRE, AGL_COLOR_DEPTH);
00087 destroy_bitmap(temp);
00088 }
00089 }
00090 }
00091
00092
00093
00094 void __allegro_gl_reset_scorer(void)
00095 {
00096 best = -1;
00097 best_score = -1;
00098 }
00099
00100
00101
00102 static int get_score(struct allegro_gl_display_info *dinfo)
00103 {
00104 int score = 0;
00105
00106 if (dinfo->colour_depth != target.colour_depth) {
00107 if (req & AGL_COLOR_DEPTH) {
00108 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00109 get_config_text("Color depth requirement not met."));
00110 return -1;
00111 }
00112 }
00113 else {
00114
00115 score += 128;
00116 }
00117
00118
00119 if (sug & AGL_COLOR_DEPTH) {
00120 if (dinfo->colour_depth < target.colour_depth)
00121 score += (96 * dinfo->colour_depth) / target.colour_depth;
00122 else
00123 score += 96 + 96 / (1 + dinfo->colour_depth - target.colour_depth);
00124 }
00125
00126
00127
00128 if ((req & AGL_RED_DEPTH)
00129 && (dinfo->pixel_size.rgba.r != target.pixel_size.rgba.r)) {
00130
00131 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00132 get_config_text("Red depth requirement not met."));
00133 return -1;
00134 }
00135
00136 if (sug & AGL_RED_DEPTH) {
00137 if (dinfo->pixel_size.rgba.r < target.pixel_size.rgba.r) {
00138 score += (16 * dinfo->pixel_size.rgba.r) / target.pixel_size.rgba.r;
00139 }
00140 else {
00141 score += 16
00142 + 16 / (1 + dinfo->pixel_size.rgba.r - target.pixel_size.rgba.r);
00143 }
00144 }
00145
00146 if ((req & AGL_GREEN_DEPTH)
00147 && (dinfo->pixel_size.rgba.g != target.pixel_size.rgba.g)) {
00148
00149 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00150 get_config_text("Green depth requirement not met."));
00151 return -1;
00152 }
00153
00154 if (sug & AGL_GREEN_DEPTH) {
00155 if (dinfo->pixel_size.rgba.g < target.pixel_size.rgba.g) {
00156 score += (16 * dinfo->pixel_size.rgba.g) / target.pixel_size.rgba.g;
00157 }
00158 else {
00159 score += 16
00160 + 16 / (1 + dinfo->pixel_size.rgba.g - target.pixel_size.rgba.g);
00161 }
00162 }
00163
00164 if ((req & AGL_BLUE_DEPTH)
00165 && (dinfo->pixel_size.rgba.b != target.pixel_size.rgba.b)) {
00166
00167 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00168 get_config_text("Blue depth requirement not met."));
00169 return -1;
00170 }
00171
00172 if (sug & AGL_BLUE_DEPTH) {
00173 if (dinfo->pixel_size.rgba.b < target.pixel_size.rgba.b) {
00174 score += (16 * dinfo->pixel_size.rgba.b) / target.pixel_size.rgba.b;
00175 }
00176 else {
00177 score += 16
00178 + 16 / (1 + dinfo->pixel_size.rgba.b - target.pixel_size.rgba.b);
00179 }
00180 }
00181
00182 if ((req & AGL_ALPHA_DEPTH)
00183 && (dinfo->pixel_size.rgba.a != target.pixel_size.rgba.a)) {
00184
00185 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00186 get_config_text("Alpha depth requirement not met."));
00187 return -1;
00188 }
00189
00190 if (sug & AGL_ALPHA_DEPTH) {
00191 if (dinfo->pixel_size.rgba.a < target.pixel_size.rgba.a) {
00192 score += (16 * dinfo->pixel_size.rgba.a) / target.pixel_size.rgba.a;
00193 }
00194 else {
00195 score += 16
00196 + 16 / (1 + dinfo->pixel_size.rgba.a - target.pixel_size.rgba.a);
00197 }
00198 }
00199
00200
00201 if ((req & AGL_ACC_RED_DEPTH)
00202 && (dinfo->accum_size.rgba.r != target.accum_size.rgba.r)) {
00203
00204 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00205 get_config_text("Accumulator Red depth requirement not met."));
00206 return -1;
00207 }
00208
00209 if (sug & AGL_ACC_RED_DEPTH) {
00210 if (dinfo->accum_size.rgba.r < target.accum_size.rgba.r) {
00211 score += (16 * dinfo->accum_size.rgba.r) / target.accum_size.rgba.r;
00212 }
00213 else {
00214 score += 16
00215 + 16 / (1 + dinfo->accum_size.rgba.r - target.accum_size.rgba.r);
00216 }
00217 }
00218
00219 if ((req & AGL_ACC_GREEN_DEPTH)
00220 && (dinfo->accum_size.rgba.g != target.accum_size.rgba.g)) {
00221
00222 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00223 get_config_text("Accumulator Green depth requirement not met."));
00224 return -1;
00225 }
00226
00227 if (sug & AGL_ACC_GREEN_DEPTH) {
00228 if (dinfo->accum_size.rgba.g < target.accum_size.rgba.g) {
00229 score += (16 * dinfo->accum_size.rgba.g) / target.accum_size.rgba.g;
00230 }
00231 else {
00232 score += 16
00233 + 16 / (1 + dinfo->accum_size.rgba.g - target.accum_size.rgba.g);
00234 }
00235 }
00236
00237 if ((req & AGL_ACC_BLUE_DEPTH)
00238 && (dinfo->accum_size.rgba.b != target.accum_size.rgba.b)) {
00239
00240 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00241 get_config_text("Accumulator Blue depth requirement not met."));
00242 return -1;
00243 }
00244
00245 if (sug & AGL_ACC_BLUE_DEPTH) {
00246 if (dinfo->accum_size.rgba.b < target.accum_size.rgba.b) {
00247 score += (16 * dinfo->accum_size.rgba.b) / target.accum_size.rgba.b;
00248 }
00249 else {
00250 score += 16
00251 + 16 / (1 + dinfo->accum_size.rgba.b - target.accum_size.rgba.b);
00252 }
00253 }
00254
00255 if ((req & AGL_ACC_ALPHA_DEPTH)
00256 && (dinfo->accum_size.rgba.a != target.accum_size.rgba.a)) {
00257
00258 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00259 get_config_text("Accumulator Alpha depth requirement not met."));
00260 return -1;
00261 }
00262
00263 if (sug & AGL_ACC_ALPHA_DEPTH) {
00264 if (dinfo->accum_size.rgba.a < target.accum_size.rgba.a) {
00265 score += (16 * dinfo->accum_size.rgba.a) / target.accum_size.rgba.a;
00266 }
00267 else {
00268 score += 16
00269 + 16 / (1 + dinfo->accum_size.rgba.a - target.accum_size.rgba.a);
00270 }
00271 }
00272
00273
00274
00275 if (!dinfo->doublebuffered != !target.doublebuffered) {
00276 if (req & AGL_DOUBLEBUFFER) {
00277 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00278 get_config_text("Double Buffer requirement not met."));
00279 return -1;
00280 }
00281 }
00282 else {
00283 score += (sug & AGL_DOUBLEBUFFER) ? 256 : 1;
00284 }
00285
00286 if (!dinfo->stereo != !target.stereo) {
00287 if (req & AGL_STEREO) {
00288 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00289 get_config_text("Stereo Buffer requirement not met."));
00290 return -1;
00291 }
00292 }
00293 else {
00294 if (sug & AGL_STEREO) {
00295 score += 128;
00296 }
00297 }
00298
00299 if ((req & AGL_AUX_BUFFERS) && (dinfo->aux_buffers < target.aux_buffers)) {
00300 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00301 get_config_text("Aux Buffer requirement not met."));
00302 return -1;
00303 }
00304
00305 if (sug & AGL_AUX_BUFFERS) {
00306 if (dinfo->aux_buffers < target.aux_buffers) {
00307 score += (64 * dinfo->aux_buffers) / target.aux_buffers;
00308 }
00309 else {
00310 score += 64 + 64 / (1 + dinfo->aux_buffers - target.aux_buffers);
00311 }
00312 }
00313
00314 if ((req & AGL_Z_DEPTH) && (dinfo->depth_size != target.depth_size)) {
00315 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00316 get_config_text("Z-Buffer requirement not met."));
00317 return -1;
00318 }
00319 if (sug & AGL_Z_DEPTH) {
00320 if (dinfo->depth_size < target.depth_size) {
00321 score += (64 * dinfo->depth_size) / target.depth_size;
00322 }
00323 else {
00324 score += 64 + 64 / (1 + dinfo->depth_size - target.depth_size);
00325 }
00326 }
00327
00328 if ((req & AGL_STENCIL_DEPTH)
00329 && (dinfo->stencil_size != target.stencil_size)) {
00330
00331 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00332 get_config_text("Stencil depth requirement not met."));
00333 return -1;
00334 }
00335
00336 if (sug & AGL_STENCIL_DEPTH) {
00337 if (dinfo->stencil_size < target.stencil_size) {
00338 score += (64 * dinfo->stencil_size) / target.stencil_size;
00339 }
00340 else {
00341 score += 64 + 64 / (1 + dinfo->stencil_size - target.stencil_size);
00342 }
00343 }
00344
00345 if ((req & AGL_RENDERMETHOD)
00346 && ((dinfo->rmethod != target.rmethod) || (target.rmethod == 2))) {
00347
00348 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00349 get_config_text("Render Method requirement not met"));
00350 return -1;
00351 }
00352
00353 if ((sug & AGL_RENDERMETHOD) && (dinfo->rmethod == target.rmethod)) {
00354 score += 1024;
00355 }
00356 else if (dinfo->rmethod == 1) {
00357 score++;
00358 }
00359
00360 if ((req & AGL_SAMPLE_BUFFERS)
00361 && (dinfo->sample_buffers != target.sample_buffers)) {
00362 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
00363 get_config_text("Multisample Buffers requirement not met"));
00364 return -1;
00365 }
00366
00367 if (sug & AGL_SAMPLE_BUFFERS) {
00368 if (dinfo->sample_buffers < target.sample_buffers) {
00369 score += (64 * dinfo->sample_buffers) / target.sample_buffers;
00370 }
00371 else {
00372 score += 64
00373 + 64 / (1 + dinfo->sample_buffers - target.sample_buffers);
00374 }
00375 }
00376
00377 if ((req & AGL_SAMPLES) && (dinfo->samples != target.samples)) {
00378 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
00379 get_config_text("Multisample Samples requirement not met"));
00380 return -1;
00381 }
00382
00383 if (sug & AGL_SAMPLES) {
00384 if (dinfo->samples < target.samples) {
00385 score += (64 * dinfo->samples) / target.samples;
00386 }
00387 else {
00388 score += 64 + 64 / (1 + dinfo->samples - target.samples);
00389 }
00390 }
00391
00392 TRACE("\tScore is : %i\n", score);
00393 return score;
00394 }
00395
00396 #undef target
00397 #undef req
00398 #undef sug
00399
00400
00401
00402 int __allegro_gl_score_config(int refnum,
00403 struct allegro_gl_display_info *dinfo)
00404 {
00405 int score = get_score(dinfo);
00406 if (score == -1) {
00407 TRACE("* Note * score_config: %s\n", allegro_gl_error);
00408 return score;
00409 }
00410
00411 if (score == best_score) {
00412
00413
00414
00415
00416 }
00417
00418 if (score > best_score) {
00419 best_score = score;
00420 best = refnum;
00421 }
00422
00423 return score;
00424 }
00425
00426
00427
00428 int __allegro_gl_best_config(void)
00429 {
00430 return best;
00431 }
00432