gcsx_resolution.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* GCSx
  2. ** RESOLUTION.CPP
  3. **
  4. ** Resolution-selection dialog
  5. */
  6. /*****************************************************************************
  7. ** Copyright (C) 2003-2006 Janson
  8. **
  9. ** This program is free software; you can redistribute it and/or modify
  10. ** it under the terms of the GNU General Public License as published by
  11. ** the Free Software Foundation; either version 2 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** This program is distributed in the hope that it will be useful,
  15. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ** GNU General Public License for more details.
  18. **
  19. ** You should have received a copy of the GNU General Public License
  20. ** along with this program; if not, write to the Free Software
  21. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  22. *****************************************************************************/
  23. #include "all.h"
  24. ResolutionDialog* ResolutionDialog::dialog = NULL;
  25. ResolutionDialog* ResolutionDialog::create() { start_func
  26. if (!dialog) {
  27. dialog = new ResolutionDialog();
  28. }
  29. return dialog;
  30. }
  31. void ResolutionDialog::destroy() { start_func
  32. if (dialog) {
  33. delete dialog;
  34. dialog = NULL;
  35. }
  36. }
  37. ResolutionDialog::ResolutionDialog() : Dialog("Select Resolution") { start_func
  38. resSelection = 1;
  39. initialized = 0;
  40. }
  41. void ResolutionDialog::chooseResolution() { start_func
  42. if (!initialized) {
  43. Widget* w = NULL;
  44. WListBox* l = NULL;
  45. SDL_Rect** vidModes = NULL;
  46. // Start with best format
  47. SDL_PixelFormat format = *(SDL_GetVideoInfo()->vfmt);
  48. // (max 32 bpp)
  49. if (format.BitsPerPixel > 32) {
  50. format.BitsPerPixel = 32;
  51. format.BytesPerPixel = 4;
  52. }
  53. w = new WStatic(ID_LABEL, "\tResolution:");
  54. w->addTo(this);
  55. l = new WListBox(ID_LISTBOX, &resSelection, 0, -1, 10);
  56. // Windowed option
  57. int found = 1;
  58. l->addItem(ListEntry("Windowed mode", found, 0, 0, 0));
  59. l->addItem(ListEntry("Windowed (no resize)", ++found, 0, 0, 0));
  60. if (!screenFullscreen()) {
  61. if (screenResizable()) {
  62. resSelection = 1;
  63. }
  64. else {
  65. resSelection = 2;
  66. }
  67. }
  68. char resDesc[80];
  69. for (;;) {
  70. vidModes = SDL_ListModes(&format, SDL_FULLSCREEN|SDL_SWSURFACE);
  71. if (vidModes == (SDL_Rect**)-1) {
  72. // We can't handle SDL's "any resolution is OK" concept
  73. fatalCrash(0, "Unlimited video modes- unhandled");
  74. }
  75. if (vidModes) {
  76. for (int pos = 0; vidModes[pos]; ++pos) {
  77. if ((vidModes[pos]->w >= 320) && (vidModes[pos]->h >= 240)) {
  78. ++found;
  79. sprintf(resDesc, "%d x %d x %dbpp", vidModes[pos]->w, vidModes[pos]->h, format.BitsPerPixel);
  80. // (current format?)
  81. if ((screenFullscreen()) &&
  82. (vidModes[pos]->w == screenWidth) &&
  83. (vidModes[pos]->h == screenHeight) &&
  84. (format.BitsPerPixel == screenBits())) {
  85. resSelection = found;
  86. }
  87. l->addItem(ListEntry(resDesc, found, vidModes[pos]->w, vidModes[pos]->h, format.BitsPerPixel));
  88. }
  89. }
  90. }
  91. // Switch downward from 32 to 24 to 16 to 15 bits
  92. if ((format.BitsPerPixel == 32) || (format.BitsPerPixel == 24)) {
  93. format.BitsPerPixel -= 8;
  94. format.BytesPerPixel -= 1;
  95. }
  96. else if (format.BitsPerPixel == 16) {
  97. format.BitsPerPixel -= 1;
  98. format.BytesPerPixel -= 1;
  99. }
  100. else break;
  101. }
  102. l->addTo(this);
  103. w = new WButton(ID_OK, messageBoxOK, Dialog::BUTTON_OK);
  104. w->addTo(this);
  105. w = new WButton(ID_CANCEL, messageBoxCancel, Dialog::BUTTON_CANCEL);
  106. w->addTo(this);
  107. makePretty(2, 0);
  108. initialized = 1;
  109. }
  110. // Hit OK?
  111. if (runModal() == ID_OK) {
  112. // Catch non-fatal video errors
  113. try {
  114. if ((resSelection == 1) || (resSelection == 2)) {
  115. selectVideoMode(screenWidth, screenHeight, -1, 0, resSelection == 1 ? 1 : 0);
  116. }
  117. else {
  118. assert(findWidget(ID_LISTBOX));
  119. const ListEntry* res = dynamic_cast<WListBox*>(findWidget(ID_LISTBOX))->findEntry(resSelection);
  120. assert(res);
  121. selectVideoMode(res->code1, res->code2, res->code3, 1, 0);
  122. }
  123. }
  124. catch (const VideoException& e) {
  125. guiErrorBox(string(e.details), errorTitleVideo);
  126. }
  127. }
  128. }