scorer.c

Go to the documentation of this file.
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 /* __allegro_gl_fill_in_info()
00021  * Will fill in missing settings by 'guessing'
00022  * what the user intended.
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     /* If all color components were set, but not the color depth */
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         /* Round depth to 8 bits */
00039         target.colour_depth = (target.colour_depth + 7) / 8;
00040     }
00041     /* If only some components were set, guess the others */
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         /* If color depth wasn't defined, figure it out */
00074         if (((req | sug) & AGL_COLOR_DEPTH) == 0) {
00075             __allegro_gl_fill_in_info();
00076         }
00077     }
00078     
00079     /* If the user forgot to set a color depth in AGL, but used the
00080      * Allegro one instead
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     /* Prefer double-buffering */
00093     if (!((req | sug) & AGL_DOUBLEBUFFER)) {
00094         allegro_gl_set(AGL_DOUBLEBUFFER, 1);
00095         allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER);
00096     }
00097 
00098     /* Prefer no multisamping */
00099     if (!((req | sug) & (AGL_SAMPLE_BUFFERS | AGL_SAMPLES))) {
00100         allegro_gl_set(AGL_SAMPLE_BUFFERS, 0);
00101         allegro_gl_set(AGL_SAMPLES,        0);
00102         allegro_gl_set(AGL_SUGGEST, AGL_SAMPLE_BUFFERS | AGL_SAMPLES);
00103     }
00104 
00105     /* Prefer monoscopic */
00106     if (!((req | sug) & AGL_STEREO)) {
00107         allegro_gl_set(AGL_STEREO, 0);
00108         allegro_gl_set(AGL_SUGGEST, AGL_STEREO);
00109     }
00110 
00111     /* Prefer unsigned normalized buffers */
00112     if (!((req | sug) & (AGL_FLOAT_COLOR | AGL_FLOAT_Z))) {
00113         allegro_gl_set(AGL_FLOAT_COLOR, 0);
00114         allegro_gl_set(AGL_FLOAT_Z, 0);
00115         allegro_gl_set(AGL_SUGGEST, AGL_FLOAT_COLOR | AGL_FLOAT_Z);
00116     }
00117 }
00118 
00119 
00120 
00121 void __allegro_gl_reset_scorer(void)
00122 {
00123     best = -1;
00124     best_score = -1;
00125 }
00126 
00127 
00128 
00129 static int get_score(struct allegro_gl_display_info *dinfo)
00130 {
00131     int score = 0;
00132 
00133     if (dinfo->colour_depth != target.colour_depth) {
00134         if (req & AGL_COLOR_DEPTH) {
00135             ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00136                       get_config_text("Color depth requirement not met."));
00137             return -1;
00138         }
00139     }
00140     else {
00141         /* If requested color depths agree */
00142         score += 128;
00143     }
00144     
00145 
00146     if (sug & AGL_COLOR_DEPTH) {
00147         if (dinfo->colour_depth < target.colour_depth)
00148             score += (96 * dinfo->colour_depth) / target.colour_depth;
00149         else
00150             score += 96 + 96 / (1 + dinfo->colour_depth - target.colour_depth);
00151     }
00152 
00153     
00154     /* check colour component widths here and Allegro formatness */
00155     if ((req & AGL_RED_DEPTH)
00156      && (dinfo->pixel_size.rgba.r != target.pixel_size.rgba.r)) {
00157 
00158         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00159                   get_config_text("Red depth requirement not met."));
00160         return -1;
00161     }
00162 
00163     if (sug & AGL_RED_DEPTH) {
00164         if (dinfo->pixel_size.rgba.r < target.pixel_size.rgba.r) {
00165             score += (16 * dinfo->pixel_size.rgba.r) / target.pixel_size.rgba.r;
00166         }
00167         else {
00168             score += 16
00169                + 16 / (1 + dinfo->pixel_size.rgba.r - target.pixel_size.rgba.r);
00170         }
00171     }
00172 
00173     if ((req & AGL_GREEN_DEPTH)
00174      && (dinfo->pixel_size.rgba.g != target.pixel_size.rgba.g)) {
00175 
00176         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00177                   get_config_text("Green depth requirement not met."));
00178         return -1;
00179     }
00180 
00181     if (sug & AGL_GREEN_DEPTH) {
00182         if (dinfo->pixel_size.rgba.g < target.pixel_size.rgba.g) {
00183             score += (16 * dinfo->pixel_size.rgba.g) / target.pixel_size.rgba.g;
00184         }
00185         else {
00186             score += 16
00187                + 16 / (1 + dinfo->pixel_size.rgba.g - target.pixel_size.rgba.g);
00188         }
00189     }
00190 
00191     if ((req & AGL_BLUE_DEPTH)
00192      && (dinfo->pixel_size.rgba.b != target.pixel_size.rgba.b)) {
00193 
00194         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00195                   get_config_text("Blue depth requirement not met."));
00196         return -1;
00197     }
00198 
00199     if (sug & AGL_BLUE_DEPTH) {
00200         if (dinfo->pixel_size.rgba.b < target.pixel_size.rgba.b) {
00201             score += (16 * dinfo->pixel_size.rgba.b) / target.pixel_size.rgba.b;
00202         }
00203         else {
00204             score += 16
00205                + 16 / (1 + dinfo->pixel_size.rgba.b - target.pixel_size.rgba.b);
00206         }
00207     }
00208 
00209     if ((req & AGL_ALPHA_DEPTH)
00210      && (dinfo->pixel_size.rgba.a != target.pixel_size.rgba.a)) {
00211 
00212         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00213                   get_config_text("Alpha depth requirement not met."));
00214         return -1;
00215     }
00216 
00217     if (sug & AGL_ALPHA_DEPTH) {
00218         if (dinfo->pixel_size.rgba.a < target.pixel_size.rgba.a) {
00219             score += (16 * dinfo->pixel_size.rgba.a) / target.pixel_size.rgba.a;
00220         }
00221         else {
00222             score += 16
00223                + 16 / (1 + dinfo->pixel_size.rgba.a - target.pixel_size.rgba.a);
00224         }
00225     }
00226 
00227 
00228     if ((req & AGL_ACC_RED_DEPTH)
00229      && (dinfo->accum_size.rgba.r != target.accum_size.rgba.r)) {
00230 
00231         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00232                  get_config_text("Accumulator Red depth requirement not met."));
00233         return -1;
00234     }
00235 
00236     if (sug & AGL_ACC_RED_DEPTH) {
00237         if (dinfo->accum_size.rgba.r < target.accum_size.rgba.r) {
00238             score += (16 * dinfo->accum_size.rgba.r) / target.accum_size.rgba.r;
00239         }
00240         else {
00241             score += 16
00242                + 16 / (1 + dinfo->accum_size.rgba.r - target.accum_size.rgba.r);
00243         }
00244     }
00245 
00246     if ((req & AGL_ACC_GREEN_DEPTH)
00247      && (dinfo->accum_size.rgba.g != target.accum_size.rgba.g)) {
00248 
00249         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00250                get_config_text("Accumulator Green depth requirement not met."));
00251         return -1;
00252     }
00253 
00254     if (sug & AGL_ACC_GREEN_DEPTH) {
00255         if (dinfo->accum_size.rgba.g < target.accum_size.rgba.g) {
00256             score += (16 * dinfo->accum_size.rgba.g) / target.accum_size.rgba.g;
00257         }
00258         else {
00259             score += 16
00260                + 16 / (1 + dinfo->accum_size.rgba.g - target.accum_size.rgba.g);
00261         }
00262     }
00263 
00264     if ((req & AGL_ACC_BLUE_DEPTH)
00265      && (dinfo->accum_size.rgba.b != target.accum_size.rgba.b)) {
00266 
00267         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00268                 get_config_text("Accumulator Blue depth requirement not met."));
00269         return -1;
00270     }
00271 
00272     if (sug & AGL_ACC_BLUE_DEPTH) {
00273         if (dinfo->accum_size.rgba.b < target.accum_size.rgba.b) {
00274             score += (16 * dinfo->accum_size.rgba.b) / target.accum_size.rgba.b;
00275         }
00276         else {
00277             score += 16
00278                + 16 / (1 + dinfo->accum_size.rgba.b - target.accum_size.rgba.b);
00279         }
00280     }
00281 
00282     if ((req & AGL_ACC_ALPHA_DEPTH)
00283      && (dinfo->accum_size.rgba.a != target.accum_size.rgba.a)) {
00284 
00285         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00286                get_config_text("Accumulator Alpha depth requirement not met."));
00287         return -1;
00288     }
00289 
00290     if (sug & AGL_ACC_ALPHA_DEPTH) {
00291         if (dinfo->accum_size.rgba.a < target.accum_size.rgba.a) {
00292             score += (16 * dinfo->accum_size.rgba.a) / target.accum_size.rgba.a;
00293         }
00294         else {
00295             score += 16
00296                + 16 / (1 + dinfo->accum_size.rgba.a - target.accum_size.rgba.a);
00297         }
00298     }
00299 
00300 
00301 
00302     if (!dinfo->doublebuffered != !target.doublebuffered) {
00303         if (req & AGL_DOUBLEBUFFER) {
00304             ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00305                          get_config_text("Double Buffer requirement not met."));
00306             return -1;
00307         }
00308     }
00309     else {
00310         score += (sug & AGL_DOUBLEBUFFER) ? 256 : 1;
00311     }
00312 
00313     if (!dinfo->stereo != !target.stereo) {
00314         if (req & AGL_STEREO) {
00315             ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00316                          get_config_text("Stereo Buffer requirement not met."));
00317             return -1;
00318         }
00319     }
00320     else {
00321         if (sug & AGL_STEREO) {
00322             score += 128;
00323         }
00324     }
00325 
00326     if ((req & AGL_AUX_BUFFERS) && (dinfo->aux_buffers < target.aux_buffers)) {
00327         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00328                   get_config_text("Aux Buffer requirement not met."));
00329         return -1;
00330     }
00331     
00332     if (sug & AGL_AUX_BUFFERS) {
00333         if (dinfo->aux_buffers < target.aux_buffers) {
00334             score += (64 * dinfo->aux_buffers) / target.aux_buffers;
00335         }
00336         else {
00337             score += 64 + 64 / (1 + dinfo->aux_buffers - target.aux_buffers);
00338         }
00339     }
00340 
00341     if ((req & AGL_Z_DEPTH) && (dinfo->depth_size != target.depth_size)) {
00342         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00343                   get_config_text("Z-Buffer requirement not met."));
00344         return -1;
00345     }
00346     if (sug & AGL_Z_DEPTH) {
00347         if (dinfo->depth_size < target.depth_size) {
00348             score += (64 * dinfo->depth_size) / target.depth_size;
00349         }
00350         else {
00351             score += 64 + 64 / (1 + dinfo->depth_size - target.depth_size);
00352         }
00353     }
00354 
00355     if ((req & AGL_STENCIL_DEPTH)
00356      && (dinfo->stencil_size != target.stencil_size)) {
00357 
00358         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00359                   get_config_text("Stencil depth requirement not met."));
00360         return -1;
00361     }
00362         
00363     if (sug & AGL_STENCIL_DEPTH) {
00364         if (dinfo->stencil_size < target.stencil_size) {
00365             score += (64 * dinfo->stencil_size) / target.stencil_size;
00366         }
00367         else {
00368             score += 64 + 64 / (1 + dinfo->stencil_size - target.stencil_size);
00369         }
00370     }
00371 
00372     if ((req & AGL_RENDERMETHOD)
00373       && ((dinfo->rmethod != target.rmethod) || (target.rmethod == 2))) {
00374 
00375         ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00376                   get_config_text("Render Method requirement not met"));
00377         return -1;
00378     }
00379 
00380     if ((sug & AGL_RENDERMETHOD) && (dinfo->rmethod == target.rmethod)) {
00381         score += 1024;
00382     }
00383     else if (dinfo->rmethod == 1) {
00384         score++; /* Add 1 for h/w accel */
00385     }
00386 
00387     if ((req & AGL_SAMPLE_BUFFERS)
00388      && (dinfo->sample_buffers != target.sample_buffers)) {
00389             ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
00390                     get_config_text("Multisample Buffers requirement not met"));
00391             return -1;
00392     }
00393         
00394     if (sug & AGL_SAMPLE_BUFFERS) {
00395         if (dinfo->sample_buffers < target.sample_buffers) {
00396             score += (64 * dinfo->sample_buffers) / target.sample_buffers;
00397         }
00398         else {
00399             score += 64
00400                    + 64 / (1 + dinfo->sample_buffers - target.sample_buffers);
00401         }
00402     }
00403 
00404     if ((req & AGL_SAMPLES) && (dinfo->samples != target.samples)) {
00405         ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
00406                 get_config_text("Multisample Samples requirement not met"));
00407         return -1;
00408     }
00409         
00410     if (sug & AGL_SAMPLES) {
00411         if (dinfo->samples < target.samples) {
00412             score += (64 * dinfo->samples) / target.samples;
00413         }
00414         else {
00415             score += 64 + 64 / (1 + dinfo->samples - target.samples);
00416         }
00417     }
00418 
00419 
00420     if (!dinfo->float_color != !target.float_color) {
00421         if (req & AGL_FLOAT_COLOR) {
00422             ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00423                       get_config_text("Float Color requirement not met."));
00424             return -1;
00425         }
00426     }
00427     else {
00428         if (sug & AGL_FLOAT_COLOR) {
00429             score += 128;
00430         }
00431     }
00432 
00433     if (!dinfo->float_depth != !target.float_depth) {
00434         if (req & AGL_FLOAT_Z) {
00435             ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
00436                       get_config_text("Float Depth requirement not met."));
00437             return -1;
00438         }
00439     }
00440     else {
00441         if (sug & AGL_FLOAT_Z) {
00442             score += 128;
00443         }
00444     }
00445     
00446     TRACE("\tScore is : %i\n", score);
00447     return score;
00448 }
00449 
00450 #undef target
00451 #undef req
00452 #undef sug
00453 
00454 
00455 
00456 int __allegro_gl_score_config(int refnum,
00457                               struct allegro_gl_display_info *dinfo)
00458 {
00459     int score = get_score(dinfo);
00460     if (score == -1) {
00461         TRACE("* Note * score_config: %s\n", allegro_gl_error);
00462         return score;
00463     }
00464     
00465     if (score == best_score) {
00466         /*
00467         TRACE("* Note * score_config: score == best_score, should we change "
00468               "scoring algorithm?\n");
00469         */
00470     }
00471 
00472     if (score > best_score) {
00473         best_score = score;
00474         best = refnum;
00475     }
00476 
00477     return score;
00478 }
00479 
00480 
00481 
00482 int __allegro_gl_best_config(void)
00483 {
00484     return best;
00485 }
00486 

Generated on Mon Apr 3 18:20:13 2006 for AllegroGL by  doxygen 1.4.6