ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/SDL/video_sdl.cpp
(Generate patch)

Comparing BasiliskII/src/SDL/video_sdl.cpp (file contents):
Revision 1.4 by gbeauche, 2004-06-24T15:25:57Z vs.
Revision 1.10 by gbeauche, 2004-06-29T21:50:22Z

# Line 35 | Line 35
35   *  - Events processing is bound to the general emulation thread as SDL requires
36   *    to PumpEvents() within the same thread as the one that called SetVideoMode().
37   *    Besides, there can't seem to be a way to call SetVideoMode() from a child thread.
38 + *  - Refresh performance is still slow. Use SDL_CreateRGBSurface()?
39 + *  - Backport hw cursor acceleration to Basilisk II?
40 + *  - Move generic Native QuickDraw acceleration routines to gfxaccel.cpp
41   */
42  
43   #include "sysdeps.h"
# Line 96 | Line 99 | static volatile bool redraw_thread_cance
99   static SDL_Thread *redraw_thread = NULL;                        // Redraw thread
100  
101   #ifdef ENABLE_VOSF
102 < static bool use_vosf = true;                                            // Flag: VOSF enabled
102 > static bool use_vosf = false;                                           // Flag: VOSF enabled
103   #else
104   static const bool use_vosf = false;                                     // VOSF not possible
105   #endif
# Line 114 | Line 117 | static int keycode_table[256];                                         // X
117  
118   // SDL variables
119   static int screen_depth;                                                        // Depth of current screen
120 + static SDL_Cursor *sdl_cursor;                                          // Copy of Mac cursor
121 + static volatile bool cursor_changed = false;            // Flag: cursor changed, redraw_func must update the cursor
122   static SDL_Color sdl_palette[256];                                      // Color palette to be used as CLUT and gamma table
123   static bool sdl_palette_changed = false;                        // Flag: Palette changed, redraw thread must set new colors
124   static const int sdl_eventmask = SDL_MOUSEBUTTONDOWNMASK | SDL_MOUSEBUTTONUPMASK | SDL_MOUSEMOTIONMASK | SDL_KEYUPMASK | SDL_KEYDOWNMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK;
# Line 255 | Line 260 | static void ErrorAlert(int error)
260   {
261          ErrorAlert(GetString(error));
262   }
263 +
264 + // Display warning alert
265 + static void WarningAlert(int warning)
266 + {
267 +        WarningAlert(GetString(warning));
268 + }
269   #endif
270  
271  
# Line 342 | Line 353 | static int sdl_depth_of_video_depth(int
353          return depth;
354   }
355  
356 < // Add mode to list of supported modes
357 < static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth)
356 > // Check wether specified mode is available
357 > static bool has_mode(int type, int width, int height)
358   {
359 <        VIDEO_MODE mode;
359 >        // FIXME: no fullscreen support yet
360 >        if (type == DISPLAY_SCREEN)
361 >                return false;
362 >
363   #ifdef SHEEPSHAVER
364 <        // Don't add 512x384 modes
364 >        // Filter out Classic resolutiosn
365          if (width == 512 && height == 384)
366 +                return false;
367 +
368 +        // Read window modes prefs
369 +        static uint32 window_modes = 0;
370 +        static uint32 screen_modes = 0;
371 +        if (window_modes == 0 || screen_modes == 0) {
372 +                window_modes = PrefsFindInt32("windowmodes");
373 +                screen_modes = PrefsFindInt32("screenmodes");
374 +                if (window_modes == 0 || screen_modes == 0)
375 +                        window_modes |= 3;                      // Allow at least 640x480 and 800x600 window modes
376 +        }
377 +
378 +        if (type == DISPLAY_WINDOW) {
379 +                int apple_mask, apple_id = find_apple_resolution(width, height);
380 +                switch (apple_id) {
381 +                case APPLE_640x480:             apple_mask = 0x01; break;
382 +                case APPLE_800x600:             apple_mask = 0x02; break;
383 +                case APPLE_1024x768:    apple_mask = 0x04; break;
384 +                case APPLE_1152x768:    apple_mask = 0x40; break;
385 +                case APPLE_1152x900:    apple_mask = 0x08; break;
386 +                case APPLE_1280x1024:   apple_mask = 0x10; break;
387 +                case APPLE_1600x1200:   apple_mask = 0x20; break;
388 +                default:                                apple_mask = 0x00; break;
389 +                }
390 +                return (window_modes & apple_mask);
391 +        }
392 + #else
393 +        return true;
394 + #endif
395 +        return false;
396 + }
397 +
398 + // Add mode to list of supported modes
399 + static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth)
400 + {
401 +        // Filter out unsupported modes
402 +        if (!has_mode(type, width, height))
403                  return;
404  
405 +        // Fill in VideoMode entry
406 +        VIDEO_MODE mode;
407 + #ifdef SHEEPSHAVER
408          // Recalculate dimensions to fit Apple modes
409          resolution_id = match_apple_resolution(width, height);
410          mode.viType = type;
# Line 359 | Line 413 | static void add_mode(int type, int width
413          VIDEO_MODE_Y = height;
414          VIDEO_MODE_RESOLUTION = resolution_id;
415          VIDEO_MODE_ROW_BYTES = bytes_per_row;
416 <        VIDEO_MODE_DEPTH = depth;
416 >        VIDEO_MODE_DEPTH = (video_depth)depth;
417          VideoModes.push_back(mode);
418   }
419  
# Line 533 | Line 587 | void driver_base::update_palette(void)
587   {
588          const VIDEO_MODE &mode = monitor.get_current_mode();
589  
590 <        if (VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT)
590 >        if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT)
591                  SDL_SetPalette(s, SDL_PHYSPAL, sdl_palette, 0, 256);
592   }
593  
# Line 564 | Line 618 | driver_window::driver_window(SDL_monitor
618          ADBSetRelMouseMode(mouse_grabbed);
619  
620          // Create surface
621 <        int depth = (VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT ? 8 : screen_depth);
621 >        int depth = ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT ? 8 : screen_depth);
622          if ((s = SDL_SetVideoMode(width, height, depth, SDL_HWSURFACE)) == NULL)
623                  return;
624  
# Line 576 | Line 630 | driver_window::driver_window(SDL_monitor
630          the_buffer = (uint8 *)vm_acquire(the_buffer_size);
631          the_buffer_copy = (uint8 *)malloc(the_buffer_size);
632          D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
633 +
634 +        // Check whether we can initialize the VOSF subsystem and it's profitable
635 +        if (!video_vosf_init(m)) {
636 +                WarningAlert(STR_VOSF_INIT_ERR);
637 +                use_vosf = false;
638 +        }
639 +        else if (!video_vosf_profitable()) {
640 +                video_vosf_exit();
641 +                printf("VOSF acceleration is not profitable on this platform, disabling it\n");
642 +                use_vosf = false;
643 +        }
644 +        if (!use_vosf) {
645 +                free(the_buffer_copy);
646 +                vm_release(the_buffer, the_buffer_size);
647 +                the_host_buffer = NULL;
648 +        }
649 + #endif
650 +        if (!use_vosf) {
651 +                // Allocate memory for frame buffer
652 +                the_buffer_size = (aligned_height + 2) * s->pitch;
653 +                the_buffer_copy = (uint8 *)calloc(1, the_buffer_size);
654 +                the_buffer = (uint8 *)calloc(1, the_buffer_size);
655 +                D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy));
656 +        }
657 +        
658 + #ifdef SHEEPSHAVER
659 +        // Create cursor
660 +        if ((sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, 0, 0)) != NULL) {
661 +                SDL_SetCursor(sdl_cursor);
662 +                cursor_changed = false;
663 +        }
664   #else
665 <        // Allocate memory for frame buffer
666 <        the_buffer_size = (aligned_height + 2) * s->pitch;
582 <        the_buffer_copy = (uint8 *)calloc(1, the_buffer_size);
583 <        the_buffer = (uint8 *)calloc(1, the_buffer_size);
584 <        D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy));
665 >        // Hide cursor
666 >        SDL_ShowCursor(0);
667   #endif
668  
669          // Set window name/class
670          set_window_name(STR_WINDOW_TITLE);
671  
590        // Hide cursor
591        SDL_ShowCursor(0);
592
672          // Init blitting routines
673          SDL_PixelFormat *f = s->format;
674          VisualFormat visualFormat;
# Line 708 | Line 787 | static void keycode_init(void)
787  
788                          if (video_driver_found) {
789                                  // Skip aliases
790 <                                static const char alias_str[] = "alias";
791 <                                if (strncmp(line, alias_str, sizeof(alias_str) - 1) == 0)
790 >                                static const char sdl_str[] = "sdl";
791 >                                if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0)
792                                          continue;
793  
794                                  // Read keycode
# Line 720 | Line 799 | static void keycode_init(void)
799                                          break;
800                          } else {
801                                  // Search for SDL video driver string
802 <                                static const char alias_sdl_str[] = "alias SDL";
803 <                                if (strncmp(line, alias_sdl_str, sizeof(alias_sdl_str) - 1) == 0) {
804 <                                        char *p = line + sizeof(alias_sdl_str);
802 >                                static const char sdl_str[] = "sdl";
803 >                                if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) {
804 >                                        char *p = line + sizeof(sdl_str);
805                                          if (strstr(video_driver, p) == video_driver)
806                                                  video_driver_found = true;
807                                  }
# Line 748 | Line 827 | bool SDL_monitor_desc::video_open(void)
827   {
828          D(bug("video_open()\n"));
829          const VIDEO_MODE &mode = get_current_mode();
830 + #if DEBUG
831 +        D(bug("Current video mode:\n"));
832 +        D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f)));
833 + #endif
834  
835          // Create display driver object of requested type
836          switch (display_type) {
# Line 763 | Line 846 | bool SDL_monitor_desc::video_open(void)
846                  return false;
847          }
848  
766 #ifdef ENABLE_VOSF
767        if (use_vosf) {
768                // Initialize the VOSF system
769                if (!video_vosf_init(*this)) {
770                        ErrorAlert(STR_VOSF_INIT_ERR);
771                return false;
772                }
773        }
774 #endif
775        
849          // Initialize VideoRefresh function
850          VideoRefreshInit();
851  
# Line 820 | Line 893 | bool VideoInit(bool classic)
893          mouse_wheel_lines = PrefsFindInt32("mousewheellines");
894  
895          // Get screen mode from preferences
896 <        const char *mode_str;
896 >        const char *mode_str = NULL;
897 > #ifndef SHEEPSHAVER
898          if (classic_mode)
899                  mode_str = "win/512/342";
900          else
901                  mode_str = PrefsFindString("screen");
902 + #endif
903  
904          // Determine display type and default dimensions
905          int default_width, default_height;
# Line 842 | Line 917 | bool VideoInit(bool classic)
917                          display_type = DISPLAY_WINDOW;
918          }
919          int max_width = 640, max_height = 480;
920 <        if (display_type == DISPLAY_SCREEN) {
921 <                SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
922 <                if (modes && modes != (SDL_Rect **)-1) {
923 <                        max_width = modes[0]->w;
924 <                        max_height = modes[0]->h;
925 <                }
920 >        SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
921 >        if (modes && modes != (SDL_Rect **)-1) {
922 >                max_width = modes[0]->w;
923 >                max_height = modes[0]->h;
924 >                if (default_width > max_width)
925 >                        default_width = max_width;
926 >                if (default_height > max_height)
927 >                        default_height = max_height;
928          }
929          if (default_width <= 0)
930                  default_width = max_width;
# Line 914 | Line 991 | bool VideoInit(bool classic)
991          }
992  
993   #ifdef SHEEPSHAVER
994 <        for (int i = 0; i < VideoModes.size(); ++i)
994 >        for (int i = 0; i < VideoModes.size(); i++)
995                  VModes[i] = VideoModes[i];
996 <
997 <        const VIDEO_MODE & mode = VideoModes[cur_mode];
998 <        D(bug("Current video mode\n"));
999 <        D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH - 0x80)));
996 >        VideoInfo *p = &VModes[VideoModes.size()];
997 >        p->viType = DIS_INVALID;        // End marker
998 >        p->viRowBytes = 0;
999 >        p->viXsize = p->viYsize = 0;
1000 >        p->viAppleMode = 0;
1001 >        p->viAppleID = 0;
1002   #endif
1003  
1004   #if DEBUG
# Line 1068 | Line 1147 | void SDL_monitor_desc::set_palette(uint8
1147          const VIDEO_MODE &mode = get_current_mode();
1148  
1149          // FIXME: how can we handle the gamma ramp?
1150 <        if (VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
1150 >        if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
1151                  return;
1152  
1153          LOCK_PALETTE;
# Line 1093 | Line 1172 | void SDL_monitor_desc::set_palette(uint8
1172                  }
1173  
1174   #ifdef ENABLE_VOSF
1175 <                // We have to redraw everything because the interpretation of pixel values changed
1176 <                LOCK_VOSF;
1177 <                PFLAG_SET_ALL;
1178 <                UNLOCK_VOSF;
1179 <                memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y);
1175 >                if (use_vosf) {
1176 >                        // We have to redraw everything because the interpretation of pixel values changed
1177 >                        LOCK_VOSF;
1178 >                        PFLAG_SET_ALL;
1179 >                        UNLOCK_VOSF;
1180 >                        memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y);
1181 >                }
1182   #endif
1183          }
1184  
# Line 1168 | Line 1249 | void SDL_monitor_desc::switch_to_current
1249   #ifdef SHEEPSHAVER
1250   bool video_can_change_cursor(void)
1251   {
1252 < //      return hw_mac_cursor_accl && (display_type != DISPLAY_SCREEN);
1172 <        return false;
1252 >        return (display_type == DISPLAY_WINDOW);
1253   }
1254   #endif
1255  
# Line 1181 | Line 1261 | bool video_can_change_cursor(void)
1261   #ifdef SHEEPSHAVER
1262   void video_set_cursor(void)
1263   {
1264 < //      cursor_changed = true;
1264 >        cursor_changed = true;
1265   }
1266   #endif
1267  
# Line 1549 | Line 1629 | void VideoInstallAccel(void)
1629  
1630  
1631   /*
1632 < *  Translate key event to Mac keycode, returns -1 if no keycode was found
1553 < *  and -2 if the key was recognized as a hotkey
1632 > *  Keyboard-related utilify functions
1633   */
1634  
1635 + static bool is_modifier_key(SDL_KeyboardEvent const & e)
1636 + {
1637 +        switch (e.keysym.sym) {
1638 +        case SDLK_NUMLOCK:
1639 +        case SDLK_CAPSLOCK:
1640 +        case SDLK_SCROLLOCK:
1641 +        case SDLK_RSHIFT:
1642 +        case SDLK_LSHIFT:
1643 +        case SDLK_RCTRL:
1644 +        case SDLK_LCTRL:
1645 +        case SDLK_RALT:
1646 +        case SDLK_LALT:
1647 +        case SDLK_RMETA:
1648 +        case SDLK_LMETA:
1649 +        case SDLK_LSUPER:
1650 +        case SDLK_RSUPER:
1651 +        case SDLK_MODE:
1652 +        case SDLK_COMPOSE:
1653 +                return true;
1654 +        }
1655 +        return false;
1656 + }
1657 +
1658   static bool is_ctrl_down(SDL_keysym const & ks)
1659   {
1660          return ctrl_down || (ks.mod & KMOD_CTRL);
1661   }
1662  
1663 +
1664 + /*
1665 + *  Translate key event to Mac keycode, returns -1 if no keycode was found
1666 + *  and -2 if the key was recognized as a hotkey
1667 + */
1668 +
1669   static int kc_decode(SDL_keysym const & ks, bool key_down)
1670   {
1671          switch (ks.sym) {
# Line 1627 | Line 1735 | static int kc_decode(SDL_keysym const &
1735          case SDLK_RCTRL: return 0x36;
1736          case SDLK_LSHIFT: return 0x38;
1737          case SDLK_RSHIFT: return 0x38;
1738 + #if (defined(__APPLE__) && defined(__MACH__))
1739 +        case SDLK_LALT: return 0x3a;
1740 +        case SDLK_RALT: return 0x3a;
1741 +        case SDLK_LMETA: return 0x37;
1742 +        case SDLK_RMETA: return 0x37;
1743 + #else
1744          case SDLK_LALT: return 0x37;
1745          case SDLK_RALT: return 0x37;
1746          case SDLK_LMETA: return 0x3a;
1747          case SDLK_RMETA: return 0x3a;
1748 + #endif
1749          case SDLK_MENU: return 0x32;
1750          case SDLK_CAPSLOCK: return 0x39;
1751          case SDLK_NUMLOCK: return 0x47;
# Line 1737 | Line 1852 | static void handle_events(void)
1852                          // Keyboard
1853                          case SDL_KEYDOWN: {
1854                                  int code = -1;
1855 <                                if (use_keycodes) {
1855 >                                if (use_keycodes && !is_modifier_key(event.key)) {
1856                                          if (event2keycode(event.key, true) != -2)       // This is called to process the hotkeys
1857                                                  code = keycode_table[event.key.keysym.scancode & 0xff];
1858                                  } else
# Line 1765 | Line 1880 | static void handle_events(void)
1880                          }
1881                          case SDL_KEYUP: {
1882                                  int code = -1;
1883 <                                if (use_keycodes) {
1883 >                                if (use_keycodes && !is_modifier_key(event.key)) {
1884                                          if (event2keycode(event.key, false) != -2)      // This is called to process the hotkeys
1885                                                  code = keycode_table[event.key.keysym.scancode & 0xff];
1886                                  } else
1887                                          code = event2keycode(event.key, false);
1888 <                                if (code >= 0 && code != 0x39) {        // Don't propagate Caps Lock releases
1889 <                                        ADBKeyUp(code);
1888 >                                if (code >= 0) {
1889 >                                        if (code == 0x39) {     // Caps Lock released
1890 >                                                if (caps_on) {
1891 >                                                        ADBKeyUp(code);
1892 >                                                        caps_on = false;
1893 >                                                } else {
1894 >                                                        ADBKeyDown(code);
1895 >                                                        caps_on = true;
1896 >                                                }
1897 >                                        } else
1898 >                                                ADBKeyUp(code);
1899                                          if (code == 0x36)
1900                                                  ctrl_down = false;
1901                                  }
# Line 1838 | Line 1962 | static void update_display_static(driver
1962  
1963          // Check for first column from left and first column from right that have changed
1964          if (high) {
1965 <                if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
1965 >                if ((int)VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
1966                          const int src_bytes_per_row = bytes_per_row;
1967                          const int dst_bytes_per_row = drv->s->pitch;
1968                          const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row;
# Line 2105 | Line 2229 | static int redraw_func(void *arg)
2229                  // Refresh display
2230                  video_refresh();
2231  
2232 + #ifdef SHEEPSHAVER
2233 +                // Set new cursor image if it was changed
2234 +                if (cursor_changed && sdl_cursor) {
2235 +                        cursor_changed = false;
2236 +                        SDL_FreeCursor(sdl_cursor);
2237 +                        sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]);
2238 +                        if (sdl_cursor)
2239 +                                SDL_SetCursor(sdl_cursor);
2240 +                }
2241 + #endif
2242 +
2243                  // Set new palette if it was changed
2244                  handle_palette_changes();
2245          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines