Main Page | Modules | File List | Globals | Related Pages

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 color depth information 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 
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         /* If requested color depths agree */
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     /* check colour component widths here and Allegro formatness */
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++; /* Add 1 for h/w accel */
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         TRACE("* Note * score_config: score == best_score, should we change "
00414               "scoring algorithm?\n");
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 

Generated on Wed Jun 30 23:59:52 2004 for AllegroGL by doxygen 1.3.5