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 if (!((req | sug) & AGL_DOUBLEBUFFER)) {
00094 allegro_gl_set(AGL_DOUBLEBUFFER, 1);
00095 allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER);
00096 }
00097
00098
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
00106 if (!((req | sug) & AGL_STEREO)) {
00107 allegro_gl_set(AGL_STEREO, 0);
00108 allegro_gl_set(AGL_SUGGEST, AGL_STEREO);
00109 }
00110
00111
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
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
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++;
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
00468
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