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