From a855d6202536ff28e5aae4f22a0f31d8f5b325d0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 21 Jan 2017 15:18:31 -0500 Subject: Port of Duke Nukem 3D This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9 --- apps/plugins/sdl/src/video/SDL_RLEaccel.c | 1941 +++++++++++++ apps/plugins/sdl/src/video/SDL_RLEaccel_c.h | 31 + apps/plugins/sdl/src/video/SDL_blit.c | 360 +++ apps/plugins/sdl/src/video/SDL_blit.h | 528 ++++ apps/plugins/sdl/src/video/SDL_blit_0.c | 471 +++ apps/plugins/sdl/src/video/SDL_blit_1.c | 523 ++++ apps/plugins/sdl/src/video/SDL_blit_A.c | 2873 +++++++++++++++++++ apps/plugins/sdl/src/video/SDL_blit_N.c | 2492 ++++++++++++++++ apps/plugins/sdl/src/video/SDL_bmp.c | 549 ++++ apps/plugins/sdl/src/video/SDL_cursor.c | 758 +++++ apps/plugins/sdl/src/video/SDL_cursor_c.h | 73 + apps/plugins/sdl/src/video/SDL_gamma.c | 233 ++ apps/plugins/sdl/src/video/SDL_glfuncs.h | 341 +++ apps/plugins/sdl/src/video/SDL_leaks.h | 31 + apps/plugins/sdl/src/video/SDL_pixels.c | 626 ++++ apps/plugins/sdl/src/video/SDL_pixels_c.h | 46 + apps/plugins/sdl/src/video/SDL_stretch.c | 358 +++ apps/plugins/sdl/src/video/SDL_stretch_c.h | 29 + apps/plugins/sdl/src/video/SDL_surface.c | 941 ++++++ apps/plugins/sdl/src/video/SDL_sysvideo.h | 427 +++ apps/plugins/sdl/src/video/SDL_video.c | 1978 +++++++++++++ apps/plugins/sdl/src/video/SDL_yuv.c | 150 + apps/plugins/sdl/src/video/SDL_yuv_mmx.c | 428 +++ apps/plugins/sdl/src/video/SDL_yuv_sw.c | 1299 +++++++++ apps/plugins/sdl/src/video/SDL_yuv_sw_c.h | 37 + apps/plugins/sdl/src/video/SDL_yuvfuncs.h | 37 + apps/plugins/sdl/src/video/Xext/README | 10 + apps/plugins/sdl/src/video/Xext/XME/xme.c | 410 +++ .../plugins/sdl/src/video/Xext/Xinerama/Xinerama.c | 324 +++ apps/plugins/sdl/src/video/Xext/Xv/Xv.c | 1151 ++++++++ apps/plugins/sdl/src/video/Xext/Xv/Xvlibint.h | 81 + apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA.c | 721 +++++ .../plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA2.c | 993 +++++++ .../plugins/sdl/src/video/Xext/Xxf86vm/XF86VMode.c | 1226 ++++++++ apps/plugins/sdl/src/video/Xext/extensions/Xext.h | 50 + .../sdl/src/video/Xext/extensions/Xinerama.h | 46 + apps/plugins/sdl/src/video/Xext/extensions/Xv.h | 129 + apps/plugins/sdl/src/video/Xext/extensions/Xvlib.h | 433 +++ .../sdl/src/video/Xext/extensions/Xvproto.h | 604 ++++ .../sdl/src/video/Xext/extensions/extutil.h | 226 ++ .../sdl/src/video/Xext/extensions/panoramiXext.h | 52 + .../sdl/src/video/Xext/extensions/panoramiXproto.h | 192 ++ .../sdl/src/video/Xext/extensions/xf86dga.h | 265 ++ .../sdl/src/video/Xext/extensions/xf86dga1.h | 169 ++ .../sdl/src/video/Xext/extensions/xf86dga1str.h | 194 ++ .../sdl/src/video/Xext/extensions/xf86dgastr.h | 344 +++ .../sdl/src/video/Xext/extensions/xf86vmode.h | 314 ++ .../sdl/src/video/Xext/extensions/xf86vmstr.h | 546 ++++ apps/plugins/sdl/src/video/Xext/extensions/xme.h | 45 + apps/plugins/sdl/src/video/aalib/SDL_aaevents.c | 202 ++ apps/plugins/sdl/src/video/aalib/SDL_aaevents_c.h | 35 + apps/plugins/sdl/src/video/aalib/SDL_aamouse.c | 35 + apps/plugins/sdl/src/video/aalib/SDL_aamouse_c.h | 26 + apps/plugins/sdl/src/video/aalib/SDL_aavideo.c | 388 +++ apps/plugins/sdl/src/video/aalib/SDL_aavideo.h | 66 + .../sdl/src/video/ataricommon/SDL_ataric2p.S | 452 +++ .../sdl/src/video/ataricommon/SDL_ataric2p_s.h | 75 + .../sdl/src/video/ataricommon/SDL_ataridevmouse.c | 159 ++ .../src/video/ataricommon/SDL_ataridevmouse_c.h | 42 + .../sdl/src/video/ataricommon/SDL_atarieddi.S | 42 + .../sdl/src/video/ataricommon/SDL_atarieddi_s.h | 54 + .../sdl/src/video/ataricommon/SDL_atarievents.c | 234 ++ .../sdl/src/video/ataricommon/SDL_atarievents_c.h | 52 + .../sdl/src/video/ataricommon/SDL_atarigl.c | 1086 +++++++ .../sdl/src/video/ataricommon/SDL_atarigl_c.h | 109 + .../sdl/src/video/ataricommon/SDL_atarikeys.h | 140 + .../sdl/src/video/ataricommon/SDL_atarimxalloc.c | 52 + .../sdl/src/video/ataricommon/SDL_atarimxalloc_c.h | 37 + .../sdl/src/video/ataricommon/SDL_atarisuper.h | 61 + .../sdl/src/video/ataricommon/SDL_biosevents.c | 131 + .../sdl/src/video/ataricommon/SDL_biosevents_c.h | 42 + .../sdl/src/video/ataricommon/SDL_gemdosevents.c | 132 + .../sdl/src/video/ataricommon/SDL_gemdosevents_c.h | 42 + .../sdl/src/video/ataricommon/SDL_ikbdevents.c | 124 + .../sdl/src/video/ataricommon/SDL_ikbdevents_c.h | 42 + .../sdl/src/video/ataricommon/SDL_ikbdinterrupt.S | 404 +++ .../src/video/ataricommon/SDL_ikbdinterrupt_s.h | 61 + .../sdl/src/video/ataricommon/SDL_xbiosevents.c | 155 + .../sdl/src/video/ataricommon/SDL_xbiosevents_c.h | 48 + .../sdl/src/video/ataricommon/SDL_xbiosinterrupt.S | 212 ++ .../src/video/ataricommon/SDL_xbiosinterrupt_s.h | 52 + apps/plugins/sdl/src/video/blank_cursor.h | 33 + apps/plugins/sdl/src/video/bwindow/SDL_BView.h | 116 + apps/plugins/sdl/src/video/bwindow/SDL_BWin.h | 290 ++ apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h | 58 + .../plugins/sdl/src/video/bwindow/SDL_sysevents.cc | 415 +++ .../sdl/src/video/bwindow/SDL_sysevents_c.h | 31 + apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc | 153 + .../plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h | 33 + apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc | 841 ++++++ apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc | 92 + apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h | 32 + apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc | 314 ++ apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h | 73 + apps/plugins/sdl/src/video/caca/SDL_cacaevents.c | 101 + apps/plugins/sdl/src/video/caca/SDL_cacaevents_c.h | 35 + apps/plugins/sdl/src/video/caca/SDL_cacavideo.c | 304 ++ apps/plugins/sdl/src/video/caca/SDL_cacavideo.h | 76 + apps/plugins/sdl/src/video/dc/SDL_dcevents.c | 152 + apps/plugins/sdl/src/video/dc/SDL_dcevents_c.h | 33 + apps/plugins/sdl/src/video/dc/SDL_dcmouse.c | 35 + apps/plugins/sdl/src/video/dc/SDL_dcmouse_c.h | 26 + apps/plugins/sdl/src/video/dc/SDL_dcvideo.c | 445 +++ apps/plugins/sdl/src/video/dc/SDL_dcvideo.h | 42 + apps/plugins/sdl/src/video/default_cursor.h | 116 + apps/plugins/sdl/src/video/dga/SDL_dgaevents.c | 163 ++ apps/plugins/sdl/src/video/dga/SDL_dgaevents_c.h | 28 + apps/plugins/sdl/src/video/dga/SDL_dgamouse.c | 35 + apps/plugins/sdl/src/video/dga/SDL_dgamouse_c.h | 26 + apps/plugins/sdl/src/video/dga/SDL_dgavideo.c | 1101 +++++++ apps/plugins/sdl/src/video/dga/SDL_dgavideo.h | 124 + .../sdl/src/video/directfb/SDL_DirectFB_events.c | 219 ++ .../sdl/src/video/directfb/SDL_DirectFB_events.h | 29 + .../sdl/src/video/directfb/SDL_DirectFB_keys.h | 135 + .../sdl/src/video/directfb/SDL_DirectFB_video.c | 1171 ++++++++ .../sdl/src/video/directfb/SDL_DirectFB_video.h | 62 + .../sdl/src/video/directfb/SDL_DirectFB_yuv.c | 290 ++ .../sdl/src/video/directfb/SDL_DirectFB_yuv.h | 38 + apps/plugins/sdl/src/video/dummy/SDL_nullevents.c | 45 + .../plugins/sdl/src/video/dummy/SDL_nullevents_c.h | 33 + apps/plugins/sdl/src/video/dummy/SDL_nullmouse.c | 33 + apps/plugins/sdl/src/video/dummy/SDL_nullmouse_c.h | 26 + apps/plugins/sdl/src/video/dummy/SDL_nullvideo.c | 239 ++ apps/plugins/sdl/src/video/dummy/SDL_nullvideo.h | 40 + apps/plugins/sdl/src/video/e_log.h | 140 + apps/plugins/sdl/src/video/e_pow.h | 302 ++ apps/plugins/sdl/src/video/e_sqrt.h | 493 ++++ apps/plugins/sdl/src/video/fbcon/3dfx_mmio.h | 56 + apps/plugins/sdl/src/video/fbcon/3dfx_regs.h | 83 + apps/plugins/sdl/src/video/fbcon/SDL_fb3dfx.c | 215 ++ apps/plugins/sdl/src/video/fbcon/SDL_fb3dfx.h | 29 + apps/plugins/sdl/src/video/fbcon/SDL_fbelo.c | 442 +++ apps/plugins/sdl/src/video/fbcon/SDL_fbelo.h | 55 + apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c | 1254 ++++++++ apps/plugins/sdl/src/video/fbcon/SDL_fbevents_c.h | 38 + apps/plugins/sdl/src/video/fbcon/SDL_fbkeys.h | 139 + apps/plugins/sdl/src/video/fbcon/SDL_fbmatrox.c | 280 ++ apps/plugins/sdl/src/video/fbcon/SDL_fbmatrox.h | 29 + apps/plugins/sdl/src/video/fbcon/SDL_fbmouse.c | 33 + apps/plugins/sdl/src/video/fbcon/SDL_fbmouse_c.h | 26 + apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c | 222 ++ apps/plugins/sdl/src/video/fbcon/SDL_fbriva.h | 36 + apps/plugins/sdl/src/video/fbcon/SDL_fbvideo.c | 1982 +++++++++++++ apps/plugins/sdl/src/video/fbcon/SDL_fbvideo.h | 200 ++ apps/plugins/sdl/src/video/fbcon/matrox_mmio.h | 51 + apps/plugins/sdl/src/video/fbcon/matrox_regs.h | 376 +++ apps/plugins/sdl/src/video/fbcon/riva_mmio.h | 449 +++ apps/plugins/sdl/src/video/fbcon/riva_regs.h | 43 + apps/plugins/sdl/src/video/gapi/SDL_gapivideo.c | 1287 +++++++++ apps/plugins/sdl/src/video/gapi/SDL_gapivideo.h | 160 ++ apps/plugins/sdl/src/video/gem/SDL_gemevents.c | 375 +++ apps/plugins/sdl/src/video/gem/SDL_gemevents_c.h | 33 + apps/plugins/sdl/src/video/gem/SDL_gemmouse.c | 205 ++ apps/plugins/sdl/src/video/gem/SDL_gemmouse_c.h | 34 + apps/plugins/sdl/src/video/gem/SDL_gemvideo.c | 1337 +++++++++ apps/plugins/sdl/src/video/gem/SDL_gemvideo.h | 191 ++ apps/plugins/sdl/src/video/gem/SDL_gemwm.c | 116 + apps/plugins/sdl/src/video/gem/SDL_gemwm_c.h | 37 + apps/plugins/sdl/src/video/ggi/SDL_ggievents.c | 264 ++ apps/plugins/sdl/src/video/ggi/SDL_ggievents_c.h | 29 + apps/plugins/sdl/src/video/ggi/SDL_ggikeys.h | 135 + apps/plugins/sdl/src/video/ggi/SDL_ggimouse.c | 32 + apps/plugins/sdl/src/video/ggi/SDL_ggimouse_c.h | 26 + apps/plugins/sdl/src/video/ggi/SDL_ggivideo.c | 378 +++ apps/plugins/sdl/src/video/ggi/SDL_ggivideo.h | 48 + apps/plugins/sdl/src/video/ipod/SDL_ipodvideo.c | 733 +++++ apps/plugins/sdl/src/video/ipod/SDL_ipodvideo.h | 38 + .../plugins/sdl/src/video/maccommon/SDL_lowvideo.h | 102 + .../sdl/src/video/maccommon/SDL_macevents.c | 746 +++++ .../sdl/src/video/maccommon/SDL_macevents_c.h | 32 + apps/plugins/sdl/src/video/maccommon/SDL_macgl.c | 197 ++ apps/plugins/sdl/src/video/maccommon/SDL_macgl_c.h | 47 + apps/plugins/sdl/src/video/maccommon/SDL_mackeys.h | 140 + .../plugins/sdl/src/video/maccommon/SDL_macmouse.c | 129 + .../sdl/src/video/maccommon/SDL_macmouse_c.h | 34 + apps/plugins/sdl/src/video/maccommon/SDL_macwm.c | 442 +++ apps/plugins/sdl/src/video/maccommon/SDL_macwm_c.h | 41 + apps/plugins/sdl/src/video/macdsp/SDL_dspvideo.c | 1422 +++++++++ apps/plugins/sdl/src/video/macdsp/SDL_dspvideo.h | 54 + apps/plugins/sdl/src/video/macrom/SDL_romvideo.c | 745 +++++ apps/plugins/sdl/src/video/macrom/SDL_romvideo.h | 29 + apps/plugins/sdl/src/video/math_private.h | 173 ++ apps/plugins/sdl/src/video/mmx.h | 704 +++++ apps/plugins/sdl/src/video/nanox/SDL_nxevents.c | 382 +++ apps/plugins/sdl/src/video/nanox/SDL_nxevents_c.h | 32 + apps/plugins/sdl/src/video/nanox/SDL_nximage.c | 230 ++ apps/plugins/sdl/src/video/nanox/SDL_nximage_c.h | 35 + apps/plugins/sdl/src/video/nanox/SDL_nxmodes.c | 84 + apps/plugins/sdl/src/video/nanox/SDL_nxmodes_c.h | 34 + apps/plugins/sdl/src/video/nanox/SDL_nxmouse.c | 79 + apps/plugins/sdl/src/video/nanox/SDL_nxmouse_c.h | 29 + apps/plugins/sdl/src/video/nanox/SDL_nxvideo.c | 544 ++++ apps/plugins/sdl/src/video/nanox/SDL_nxvideo.h | 96 + apps/plugins/sdl/src/video/nanox/SDL_nxwm.c | 61 + apps/plugins/sdl/src/video/nanox/SDL_nxwm_c.h | 32 + apps/plugins/sdl/src/video/nds/SDL_ndsevents.c | 83 + apps/plugins/sdl/src/video/nds/SDL_ndsevents_c.h | 51 + apps/plugins/sdl/src/video/nds/SDL_ndsmouse.c | 34 + apps/plugins/sdl/src/video/nds/SDL_ndsmouse_c.h | 26 + apps/plugins/sdl/src/video/nds/SDL_ndsvideo.c | 500 ++++ apps/plugins/sdl/src/video/nds/SDL_ndsvideo.h | 61 + apps/plugins/sdl/src/video/os2fslib/SDL_os2fslib.c | 3018 ++++++++++++++++++++ apps/plugins/sdl/src/video/os2fslib/SDL_os2fslib.h | 71 + apps/plugins/sdl/src/video/os2fslib/SDL_vkeys.h | 74 + apps/plugins/sdl/src/video/photon/SDL_ph_events.c | 624 ++++ .../plugins/sdl/src/video/photon/SDL_ph_events_c.h | 37 + apps/plugins/sdl/src/video/photon/SDL_ph_gl.c | 406 +++ apps/plugins/sdl/src/video/photon/SDL_ph_gl.h | 41 + apps/plugins/sdl/src/video/photon/SDL_ph_image.c | 1059 +++++++ apps/plugins/sdl/src/video/photon/SDL_ph_image_c.h | 59 + apps/plugins/sdl/src/video/photon/SDL_ph_modes.c | 390 +++ apps/plugins/sdl/src/video/photon/SDL_ph_modes_c.h | 43 + apps/plugins/sdl/src/video/photon/SDL_ph_mouse.c | 220 ++ apps/plugins/sdl/src/video/photon/SDL_ph_mouse_c.h | 39 + apps/plugins/sdl/src/video/photon/SDL_ph_video.c | 648 +++++ apps/plugins/sdl/src/video/photon/SDL_ph_video.h | 157 + apps/plugins/sdl/src/video/photon/SDL_ph_wm.c | 118 + apps/plugins/sdl/src/video/photon/SDL_ph_wm_c.h | 37 + apps/plugins/sdl/src/video/photon/SDL_phyuv.c | 504 ++++ apps/plugins/sdl/src/video/photon/SDL_phyuv_c.h | 62 + apps/plugins/sdl/src/video/picogui/SDL_pgevents.c | 117 + .../plugins/sdl/src/video/picogui/SDL_pgevents_c.h | 37 + apps/plugins/sdl/src/video/picogui/SDL_pgvideo.c | 364 +++ apps/plugins/sdl/src/video/picogui/SDL_pgvideo.h | 50 + apps/plugins/sdl/src/video/ps2gs/SDL_gsevents.c | 977 +++++++ apps/plugins/sdl/src/video/ps2gs/SDL_gsevents_c.h | 38 + apps/plugins/sdl/src/video/ps2gs/SDL_gskeys.h | 139 + apps/plugins/sdl/src/video/ps2gs/SDL_gsmouse.c | 146 + apps/plugins/sdl/src/video/ps2gs/SDL_gsmouse_c.h | 37 + apps/plugins/sdl/src/video/ps2gs/SDL_gsvideo.c | 689 +++++ apps/plugins/sdl/src/video/ps2gs/SDL_gsvideo.h | 95 + apps/plugins/sdl/src/video/ps2gs/SDL_gsyuv.c | 461 +++ apps/plugins/sdl/src/video/ps2gs/SDL_gsyuv_c.h | 37 + apps/plugins/sdl/src/video/ps3/SDL_ps3events.c | 44 + apps/plugins/sdl/src/video/ps3/SDL_ps3events_c.h | 41 + apps/plugins/sdl/src/video/ps3/SDL_ps3video.c | 621 ++++ apps/plugins/sdl/src/video/ps3/SDL_ps3video.h | 165 ++ apps/plugins/sdl/src/video/ps3/SDL_ps3yuv.c | 340 +++ apps/plugins/sdl/src/video/ps3/SDL_ps3yuv_c.h | 44 + apps/plugins/sdl/src/video/ps3/spulibs/Makefile | 83 + .../sdl/src/video/ps3/spulibs/bilin_scaler.c | 2050 +++++++++++++ apps/plugins/sdl/src/video/ps3/spulibs/fb_writer.c | 193 ++ .../plugins/sdl/src/video/ps3/spulibs/spu_common.h | 108 + .../sdl/src/video/ps3/spulibs/yuv2rgb_converter.c | 629 ++++ apps/plugins/sdl/src/video/qtopia/SDL_QPEApp.cc | 63 + apps/plugins/sdl/src/video/qtopia/SDL_QPEApp.h | 33 + apps/plugins/sdl/src/video/qtopia/SDL_QWin.cc | 527 ++++ apps/plugins/sdl/src/video/qtopia/SDL_QWin.h | 110 + apps/plugins/sdl/src/video/qtopia/SDL_lowvideo.h | 65 + apps/plugins/sdl/src/video/qtopia/SDL_sysevents.cc | 269 ++ .../plugins/sdl/src/video/qtopia/SDL_sysevents_c.h | 31 + apps/plugins/sdl/src/video/qtopia/SDL_sysmouse.cc | 56 + apps/plugins/sdl/src/video/qtopia/SDL_sysmouse_c.h | 32 + apps/plugins/sdl/src/video/qtopia/SDL_sysvideo.cc | 403 +++ apps/plugins/sdl/src/video/qtopia/SDL_syswm.cc | 35 + apps/plugins/sdl/src/video/qtopia/SDL_syswm_c.h | 28 + apps/plugins/sdl/src/video/quartz/CGS.h | 84 + .../sdl/src/video/quartz/SDL_QuartzEvents.m | 1063 +++++++ apps/plugins/sdl/src/video/quartz/SDL_QuartzGL.m | 292 ++ apps/plugins/sdl/src/video/quartz/SDL_QuartzKeys.h | 146 + .../plugins/sdl/src/video/quartz/SDL_QuartzVideo.h | 229 ++ .../plugins/sdl/src/video/quartz/SDL_QuartzVideo.m | 1689 +++++++++++ apps/plugins/sdl/src/video/quartz/SDL_QuartzWM.h | 27 + apps/plugins/sdl/src/video/quartz/SDL_QuartzWM.m | 444 +++ .../sdl/src/video/quartz/SDL_QuartzWindow.h | 51 + .../sdl/src/video/quartz/SDL_QuartzWindow.m | 231 ++ apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S | 116 + .../src/video/riscos/SDL_riscosFullScreenVideo.c | 777 +++++ .../sdl/src/video/riscos/SDL_riscosevents.c | 549 ++++ .../sdl/src/video/riscos/SDL_riscosevents_c.h | 34 + .../plugins/sdl/src/video/riscos/SDL_riscosmouse.c | 371 +++ .../sdl/src/video/riscos/SDL_riscosmouse_c.h | 44 + .../sdl/src/video/riscos/SDL_riscossprite.c | 265 ++ apps/plugins/sdl/src/video/riscos/SDL_riscostask.c | 350 +++ apps/plugins/sdl/src/video/riscos/SDL_riscostask.h | 39 + .../plugins/sdl/src/video/riscos/SDL_riscosvideo.c | 316 ++ .../plugins/sdl/src/video/riscos/SDL_riscosvideo.h | 62 + apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c | 330 +++ apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c | 501 ++++ .../sdl/src/video/rockbox/SDL_rockboxvideo.c | 793 +++++ .../sdl/src/video/rockbox/SDL_rockboxvideo.h | 44 + apps/plugins/sdl/src/video/rockbox/keymaps_extra.h | 40 + apps/plugins/sdl/src/video/svga/SDL_svgaevents.c | 412 +++ apps/plugins/sdl/src/video/svga/SDL_svgaevents_c.h | 35 + apps/plugins/sdl/src/video/svga/SDL_svgamouse.c | 33 + apps/plugins/sdl/src/video/svga/SDL_svgamouse_c.h | 26 + apps/plugins/sdl/src/video/svga/SDL_svgavideo.c | 584 ++++ apps/plugins/sdl/src/video/svga/SDL_svgavideo.h | 58 + .../sdl/src/video/symbian/EKA1/SDL_epocevents.cpp | 626 ++++ .../sdl/src/video/symbian/EKA1/SDL_epocvideo.cpp | 1356 +++++++++ .../sdl/src/video/symbian/EKA1/SDL_epocvideo.h | 34 + .../sdl/src/video/symbian/EKA2/SDL_epocevents.cpp | 521 ++++ .../sdl/src/video/symbian/EKA2/SDL_epocvideo.cpp | 594 ++++ .../sdl/src/video/symbian/EKA2/SDL_epocvideo.h | 51 + apps/plugins/sdl/src/video/symbian/EKA2/dsa.cpp | 1505 ++++++++++ .../plugins/sdl/src/video/symbian/EKA2/dsa_new.cpp | 1443 ++++++++++ .../plugins/sdl/src/video/symbian/EKA2/dsa_old.cpp | 1075 +++++++ .../sdl/src/video/symbian/SDL_epocevents_c.h | 60 + apps/plugins/sdl/src/video/vgl/SDL_vglevents.c | 299 ++ apps/plugins/sdl/src/video/vgl/SDL_vglevents_c.h | 155 + apps/plugins/sdl/src/video/vgl/SDL_vglmouse.c | 56 + apps/plugins/sdl/src/video/vgl/SDL_vglmouse_c.h | 32 + apps/plugins/sdl/src/video/vgl/SDL_vglvideo.c | 624 ++++ apps/plugins/sdl/src/video/vgl/SDL_vglvideo.h | 65 + .../plugins/sdl/src/video/wincommon/SDL_lowvideo.h | 152 + .../sdl/src/video/wincommon/SDL_sysevents.c | 855 ++++++ .../plugins/sdl/src/video/wincommon/SDL_sysmouse.c | 259 ++ .../sdl/src/video/wincommon/SDL_sysmouse_c.h | 33 + apps/plugins/sdl/src/video/wincommon/SDL_syswm.c | 297 ++ apps/plugins/sdl/src/video/wincommon/SDL_syswm_c.h | 35 + apps/plugins/sdl/src/video/wincommon/SDL_wingl.c | 659 +++++ apps/plugins/sdl/src/video/wincommon/SDL_wingl_c.h | 135 + apps/plugins/sdl/src/video/wincommon/wmmsg.h | 1030 +++++++ apps/plugins/sdl/src/video/windib/SDL_dibevents.c | 704 +++++ .../plugins/sdl/src/video/windib/SDL_dibevents_c.h | 35 + apps/plugins/sdl/src/video/windib/SDL_dibvideo.c | 1323 +++++++++ apps/plugins/sdl/src/video/windib/SDL_dibvideo.h | 59 + .../sdl/src/video/windib/SDL_gapidibvideo.h | 56 + apps/plugins/sdl/src/video/windib/SDL_vkeys.h | 75 + apps/plugins/sdl/src/video/windx5/SDL_dx5events.c | 1005 +++++++ .../plugins/sdl/src/video/windx5/SDL_dx5events_c.h | 37 + apps/plugins/sdl/src/video/windx5/SDL_dx5video.c | 2537 ++++++++++++++++ apps/plugins/sdl/src/video/windx5/SDL_dx5video.h | 61 + apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c | 296 ++ apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h | 38 + apps/plugins/sdl/src/video/windx5/directx.h | 97 + .../sdl/src/video/wscons/SDL_wsconsevents.c | 233 ++ .../sdl/src/video/wscons/SDL_wsconsevents_c.h | 36 + .../plugins/sdl/src/video/wscons/SDL_wsconsmouse.c | 33 + .../sdl/src/video/wscons/SDL_wsconsmouse_c.h | 26 + .../plugins/sdl/src/video/wscons/SDL_wsconsvideo.c | 609 ++++ .../plugins/sdl/src/video/wscons/SDL_wsconsvideo.h | 76 + apps/plugins/sdl/src/video/x11/SDL_x11dga.c | 90 + apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h | 33 + apps/plugins/sdl/src/video/x11/SDL_x11dyn.c | 222 ++ apps/plugins/sdl/src/video/x11/SDL_x11dyn.h | 93 + apps/plugins/sdl/src/video/x11/SDL_x11events.c | 1414 +++++++++ apps/plugins/sdl/src/video/x11/SDL_x11events_c.h | 34 + apps/plugins/sdl/src/video/x11/SDL_x11gamma.c | 142 + apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h | 32 + apps/plugins/sdl/src/video/x11/SDL_x11gl.c | 577 ++++ apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h | 99 + apps/plugins/sdl/src/video/x11/SDL_x11image.c | 316 ++ apps/plugins/sdl/src/video/x11/SDL_x11image_c.h | 38 + apps/plugins/sdl/src/video/x11/SDL_x11modes.c | 1143 ++++++++ apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h | 43 + apps/plugins/sdl/src/video/x11/SDL_x11mouse.c | 288 ++ apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h | 33 + apps/plugins/sdl/src/video/x11/SDL_x11sym.h | 201 ++ apps/plugins/sdl/src/video/x11/SDL_x11video.c | 1571 ++++++++++ apps/plugins/sdl/src/video/x11/SDL_x11video.h | 214 ++ apps/plugins/sdl/src/video/x11/SDL_x11wm.c | 434 +++ apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h | 34 + apps/plugins/sdl/src/video/x11/SDL_x11yuv.c | 538 ++++ apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h | 41 + apps/plugins/sdl/src/video/xbios/SDL_xbios.c | 1116 ++++++++ apps/plugins/sdl/src/video/xbios/SDL_xbios.h | 111 + .../plugins/sdl/src/video/xbios/SDL_xbios_blowup.c | 77 + .../plugins/sdl/src/video/xbios/SDL_xbios_blowup.h | 86 + .../sdl/src/video/xbios/SDL_xbios_centscreen.c | 104 + .../sdl/src/video/xbios/SDL_xbios_centscreen.h | 114 + apps/plugins/sdl/src/video/xbios/SDL_xbios_milan.c | 106 + apps/plugins/sdl/src/video/xbios/SDL_xbios_milan.h | 129 + apps/plugins/sdl/src/video/xbios/SDL_xbios_sb3.c | 83 + apps/plugins/sdl/src/video/xbios/SDL_xbios_sb3.h | 82 + .../sdl/src/video/xbios/SDL_xbios_tveille.c | 63 + .../sdl/src/video/xbios/SDL_xbios_tveille.h | 64 + 367 files changed, 114272 insertions(+) create mode 100644 apps/plugins/sdl/src/video/SDL_RLEaccel.c create mode 100644 apps/plugins/sdl/src/video/SDL_RLEaccel_c.h create mode 100644 apps/plugins/sdl/src/video/SDL_blit.c create mode 100644 apps/plugins/sdl/src/video/SDL_blit.h create mode 100644 apps/plugins/sdl/src/video/SDL_blit_0.c create mode 100644 apps/plugins/sdl/src/video/SDL_blit_1.c create mode 100644 apps/plugins/sdl/src/video/SDL_blit_A.c create mode 100644 apps/plugins/sdl/src/video/SDL_blit_N.c create mode 100644 apps/plugins/sdl/src/video/SDL_bmp.c create mode 100644 apps/plugins/sdl/src/video/SDL_cursor.c create mode 100644 apps/plugins/sdl/src/video/SDL_cursor_c.h create mode 100644 apps/plugins/sdl/src/video/SDL_gamma.c create mode 100644 apps/plugins/sdl/src/video/SDL_glfuncs.h create mode 100644 apps/plugins/sdl/src/video/SDL_leaks.h create mode 100644 apps/plugins/sdl/src/video/SDL_pixels.c create mode 100644 apps/plugins/sdl/src/video/SDL_pixels_c.h create mode 100644 apps/plugins/sdl/src/video/SDL_stretch.c create mode 100644 apps/plugins/sdl/src/video/SDL_stretch_c.h create mode 100644 apps/plugins/sdl/src/video/SDL_surface.c create mode 100644 apps/plugins/sdl/src/video/SDL_sysvideo.h create mode 100644 apps/plugins/sdl/src/video/SDL_video.c create mode 100644 apps/plugins/sdl/src/video/SDL_yuv.c create mode 100644 apps/plugins/sdl/src/video/SDL_yuv_mmx.c create mode 100644 apps/plugins/sdl/src/video/SDL_yuv_sw.c create mode 100644 apps/plugins/sdl/src/video/SDL_yuv_sw_c.h create mode 100644 apps/plugins/sdl/src/video/SDL_yuvfuncs.h create mode 100644 apps/plugins/sdl/src/video/Xext/README create mode 100644 apps/plugins/sdl/src/video/Xext/XME/xme.c create mode 100644 apps/plugins/sdl/src/video/Xext/Xinerama/Xinerama.c create mode 100644 apps/plugins/sdl/src/video/Xext/Xv/Xv.c create mode 100644 apps/plugins/sdl/src/video/Xext/Xv/Xvlibint.h create mode 100644 apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA.c create mode 100644 apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA2.c create mode 100644 apps/plugins/sdl/src/video/Xext/Xxf86vm/XF86VMode.c create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/Xext.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/Xinerama.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/Xv.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/Xvlib.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/Xvproto.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/extutil.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/panoramiXext.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/panoramiXproto.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86dga.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86dga1.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86dga1str.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86dgastr.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86vmode.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xf86vmstr.h create mode 100644 apps/plugins/sdl/src/video/Xext/extensions/xme.h create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aaevents.c create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aaevents_c.h create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aamouse.c create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aamouse_c.h create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aavideo.c create mode 100644 apps/plugins/sdl/src/video/aalib/SDL_aavideo.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p.S create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p_s.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ataridevmouse.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ataridevmouse_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarieddi.S create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarieddi_s.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarievents.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarievents_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarigl.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarigl_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarikeys.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarimxalloc.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarimxalloc_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_atarisuper.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_biosevents.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_biosevents_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_gemdosevents.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_gemdosevents_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ikbdevents.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ikbdevents_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ikbdinterrupt.S create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_ikbdinterrupt_s.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_xbiosevents.c create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_xbiosevents_c.h create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_xbiosinterrupt.S create mode 100644 apps/plugins/sdl/src/video/ataricommon/SDL_xbiosinterrupt_s.h create mode 100644 apps/plugins/sdl/src/video/blank_cursor.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_BView.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_BWin.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysevents_c.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc create mode 100644 apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h create mode 100644 apps/plugins/sdl/src/video/caca/SDL_cacaevents.c create mode 100644 apps/plugins/sdl/src/video/caca/SDL_cacaevents_c.h create mode 100644 apps/plugins/sdl/src/video/caca/SDL_cacavideo.c create mode 100644 apps/plugins/sdl/src/video/caca/SDL_cacavideo.h create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcevents.c create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcevents_c.h create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcmouse.c create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcmouse_c.h create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcvideo.c create mode 100644 apps/plugins/sdl/src/video/dc/SDL_dcvideo.h create mode 100644 apps/plugins/sdl/src/video/default_cursor.h create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgaevents.c create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgaevents_c.h create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgamouse.c create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgamouse_c.h create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgavideo.c create mode 100644 apps/plugins/sdl/src/video/dga/SDL_dgavideo.h create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_events.c create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_events.h create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_keys.h create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_video.c create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_video.h create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_yuv.c create mode 100644 apps/plugins/sdl/src/video/directfb/SDL_DirectFB_yuv.h create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullevents.c create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullevents_c.h create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullmouse.c create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullmouse_c.h create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullvideo.c create mode 100644 apps/plugins/sdl/src/video/dummy/SDL_nullvideo.h create mode 100644 apps/plugins/sdl/src/video/e_log.h create mode 100644 apps/plugins/sdl/src/video/e_pow.h create mode 100644 apps/plugins/sdl/src/video/e_sqrt.h create mode 100644 apps/plugins/sdl/src/video/fbcon/3dfx_mmio.h create mode 100644 apps/plugins/sdl/src/video/fbcon/3dfx_regs.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fb3dfx.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fb3dfx.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbelo.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbelo.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbevents.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbevents_c.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbkeys.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbmatrox.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbmatrox.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbmouse.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbmouse_c.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbriva.h create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbvideo.c create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbvideo.h create mode 100644 apps/plugins/sdl/src/video/fbcon/matrox_mmio.h create mode 100644 apps/plugins/sdl/src/video/fbcon/matrox_regs.h create mode 100644 apps/plugins/sdl/src/video/fbcon/riva_mmio.h create mode 100644 apps/plugins/sdl/src/video/fbcon/riva_regs.h create mode 100644 apps/plugins/sdl/src/video/gapi/SDL_gapivideo.c create mode 100644 apps/plugins/sdl/src/video/gapi/SDL_gapivideo.h create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemevents.c create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemevents_c.h create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemmouse.c create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemmouse_c.h create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemvideo.c create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemvideo.h create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemwm.c create mode 100644 apps/plugins/sdl/src/video/gem/SDL_gemwm_c.h create mode 100644 apps/plugins/sdl/src/video/ggi/SDL_ggievents.c create mode 100755 apps/plugins/sdl/src/video/ggi/SDL_ggievents_c.h create mode 100644 apps/plugins/sdl/src/video/ggi/SDL_ggikeys.h create mode 100644 apps/plugins/sdl/src/video/ggi/SDL_ggimouse.c create mode 100755 apps/plugins/sdl/src/video/ggi/SDL_ggimouse_c.h create mode 100644 apps/plugins/sdl/src/video/ggi/SDL_ggivideo.c create mode 100644 apps/plugins/sdl/src/video/ggi/SDL_ggivideo.h create mode 100644 apps/plugins/sdl/src/video/ipod/SDL_ipodvideo.c create mode 100644 apps/plugins/sdl/src/video/ipod/SDL_ipodvideo.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_lowvideo.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macevents.c create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macevents_c.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macgl.c create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macgl_c.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_mackeys.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macmouse.c create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macmouse_c.h create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macwm.c create mode 100644 apps/plugins/sdl/src/video/maccommon/SDL_macwm_c.h create mode 100644 apps/plugins/sdl/src/video/macdsp/SDL_dspvideo.c create mode 100644 apps/plugins/sdl/src/video/macdsp/SDL_dspvideo.h create mode 100644 apps/plugins/sdl/src/video/macrom/SDL_romvideo.c create mode 100644 apps/plugins/sdl/src/video/macrom/SDL_romvideo.h create mode 100644 apps/plugins/sdl/src/video/math_private.h create mode 100644 apps/plugins/sdl/src/video/mmx.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxevents.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxevents_c.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nximage.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nximage_c.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxmodes.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxmodes_c.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxmouse.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxmouse_c.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxvideo.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxvideo.h create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxwm.c create mode 100644 apps/plugins/sdl/src/video/nanox/SDL_nxwm_c.h create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsevents.c create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsevents_c.h create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsmouse.c create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsmouse_c.h create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsvideo.c create mode 100644 apps/plugins/sdl/src/video/nds/SDL_ndsvideo.h create mode 100644 apps/plugins/sdl/src/video/os2fslib/SDL_os2fslib.c create mode 100644 apps/plugins/sdl/src/video/os2fslib/SDL_os2fslib.h create mode 100644 apps/plugins/sdl/src/video/os2fslib/SDL_vkeys.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_events.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_events_c.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_gl.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_gl.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_image.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_image_c.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_modes.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_modes_c.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_mouse.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_mouse_c.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_video.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_video.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_wm.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_ph_wm_c.h create mode 100644 apps/plugins/sdl/src/video/photon/SDL_phyuv.c create mode 100644 apps/plugins/sdl/src/video/photon/SDL_phyuv_c.h create mode 100644 apps/plugins/sdl/src/video/picogui/SDL_pgevents.c create mode 100644 apps/plugins/sdl/src/video/picogui/SDL_pgevents_c.h create mode 100644 apps/plugins/sdl/src/video/picogui/SDL_pgvideo.c create mode 100644 apps/plugins/sdl/src/video/picogui/SDL_pgvideo.h create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsevents.c create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsevents_c.h create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gskeys.h create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsmouse.c create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsmouse_c.h create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsvideo.c create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsvideo.h create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsyuv.c create mode 100644 apps/plugins/sdl/src/video/ps2gs/SDL_gsyuv_c.h create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3events.c create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3events_c.h create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3video.c create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3video.h create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3yuv.c create mode 100644 apps/plugins/sdl/src/video/ps3/SDL_ps3yuv_c.h create mode 100644 apps/plugins/sdl/src/video/ps3/spulibs/Makefile create mode 100644 apps/plugins/sdl/src/video/ps3/spulibs/bilin_scaler.c create mode 100644 apps/plugins/sdl/src/video/ps3/spulibs/fb_writer.c create mode 100644 apps/plugins/sdl/src/video/ps3/spulibs/spu_common.h create mode 100644 apps/plugins/sdl/src/video/ps3/spulibs/yuv2rgb_converter.c create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_QPEApp.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_QPEApp.h create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_QWin.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_QWin.h create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_lowvideo.h create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_sysevents.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_sysevents_c.h create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_sysmouse.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_sysmouse_c.h create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_sysvideo.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_syswm.cc create mode 100644 apps/plugins/sdl/src/video/qtopia/SDL_syswm_c.h create mode 100644 apps/plugins/sdl/src/video/quartz/CGS.h create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzEvents.m create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzGL.m create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzKeys.h create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzVideo.h create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzVideo.m create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzWM.h create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzWM.m create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzWindow.h create mode 100644 apps/plugins/sdl/src/video/quartz/SDL_QuartzWindow.m create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscostask.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscostask.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c create mode 100644 apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c create mode 100644 apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.h create mode 100644 apps/plugins/sdl/src/video/rockbox/keymaps_extra.h create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgaevents.c create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgaevents_c.h create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgamouse.c create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgamouse_c.h create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgavideo.c create mode 100644 apps/plugins/sdl/src/video/svga/SDL_svgavideo.h create mode 100644 apps/plugins/sdl/src/video/symbian/EKA1/SDL_epocevents.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA1/SDL_epocvideo.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA1/SDL_epocvideo.h create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/SDL_epocevents.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/SDL_epocvideo.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/SDL_epocvideo.h create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/dsa.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/dsa_new.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/EKA2/dsa_old.cpp create mode 100644 apps/plugins/sdl/src/video/symbian/SDL_epocevents_c.h create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglevents.c create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglevents_c.h create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglmouse.c create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglmouse_c.h create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglvideo.c create mode 100644 apps/plugins/sdl/src/video/vgl/SDL_vglvideo.h create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_lowvideo.h create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_sysevents.c create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_sysmouse.c create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_sysmouse_c.h create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_syswm.c create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_syswm_c.h create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_wingl.c create mode 100644 apps/plugins/sdl/src/video/wincommon/SDL_wingl_c.h create mode 100644 apps/plugins/sdl/src/video/wincommon/wmmsg.h create mode 100644 apps/plugins/sdl/src/video/windib/SDL_dibevents.c create mode 100644 apps/plugins/sdl/src/video/windib/SDL_dibevents_c.h create mode 100644 apps/plugins/sdl/src/video/windib/SDL_dibvideo.c create mode 100644 apps/plugins/sdl/src/video/windib/SDL_dibvideo.h create mode 100644 apps/plugins/sdl/src/video/windib/SDL_gapidibvideo.h create mode 100644 apps/plugins/sdl/src/video/windib/SDL_vkeys.h create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5events.c create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5events_c.h create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5video.c create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5video.h create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5yuv.c create mode 100644 apps/plugins/sdl/src/video/windx5/SDL_dx5yuv_c.h create mode 100644 apps/plugins/sdl/src/video/windx5/directx.h create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsevents.c create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsevents_c.h create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse.c create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsmouse_c.h create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.c create mode 100644 apps/plugins/sdl/src/video/wscons/SDL_wsconsvideo.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11dga.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11dga_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11dyn.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11dyn.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11events.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11events_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11gamma.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11gamma_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11gl.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11gl_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11image.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11image_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11modes.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11modes_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11mouse.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11mouse_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11sym.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11video.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11video.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11wm.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11wm_c.h create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11yuv.c create mode 100644 apps/plugins/sdl/src/video/x11/SDL_x11yuv_c.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_blowup.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_blowup.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_centscreen.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_centscreen.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_milan.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_milan.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_sb3.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_sb3.h create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_tveille.c create mode 100644 apps/plugins/sdl/src/video/xbios/SDL_xbios_tveille.h (limited to 'apps/plugins/sdl/src/video') diff --git a/apps/plugins/sdl/src/video/SDL_RLEaccel.c b/apps/plugins/sdl/src/video/SDL_RLEaccel.c new file mode 100644 index 0000000000..d4b191c272 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_RLEaccel.c @@ -0,0 +1,1941 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + * RLE encoding for software colorkey and alpha-channel acceleration + * + * Original version by Sam Lantinga + * + * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and + * decoder. Added per-surface alpha blitter. Added per-pixel alpha + * format, encoder and blitter. + * + * Many thanks to Xark and johns for hints, benchmarks and useful comments + * leading to this code. + * + * Welcome to Macro Mayhem. + */ + +/* + * The encoding translates the image data to a stream of segments of the form + * + * + * + * where is the number of transparent pixels to skip, + * is the number of opaque pixels to blit, + * and are the pixels themselves. + * + * This basic structure is used both for colorkeyed surfaces, used for simple + * binary transparency and for per-surface alpha blending, and for surfaces + * with per-pixel alpha. The details differ, however: + * + * Encoding of colorkeyed surfaces: + * + * Encoded pixels always have the same format as the target surface. + * and are unsigned 8 bit integers, except for 32 bit depth + * where they are 16 bit. This makes the pixel data aligned at all times. + * Segments never wrap around from one scan line to the next. + * + * The end of the sequence is marked by a zero , pair at the * + * beginning of a line. + * + * Encoding of surfaces with per-pixel alpha: + * + * The sequence begins with a struct RLEDestFormat describing the target + * pixel format, to provide reliable un-encoding. + * + * Each scan line is encoded twice: First all completely opaque pixels, + * encoded in the target format as described above, and then all + * partially transparent (translucent) pixels (where 1 <= alpha <= 254), + * in the following 32-bit format: + * + * For 32-bit targets, each pixel has the target RGB format but with + * the alpha value occupying the highest 8 bits. The and + * counts are 16 bit. + * + * For 16-bit targets, each pixel has the target RGB format, but with + * the middle component (usually green) shifted 16 steps to the left, + * and the hole filled with the 5 most significant bits of the alpha value. + * i.e. if the target has the format rrrrrggggggbbbbb, + * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb. + * The and counts are 8 bit for the opaque lines, 16 bit + * for the translucent lines. Two padding bytes may be inserted + * before each translucent line to keep them 32-bit aligned. + * + * The end of the sequence is marked by a zero , pair at the + * beginning of an opaque line. + */ + +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_RLEaccel_c.h" + +/* Force MMX to 0; this blows up on almost every major compiler now. --ryan. */ +#if 0 && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES +#define MMX_ASMBLIT +#endif + +#ifdef MMX_ASMBLIT +#include "mmx.h" +#include "SDL_cpuinfo.h" +#endif + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#define PIXEL_COPY(to, from, len, bpp) \ +do { \ + if(bpp == 4) { \ + SDL_memcpy4(to, from, (size_t)(len)); \ + } else { \ + SDL_memcpy(to, from, (size_t)(len) * (bpp)); \ + } \ +} while(0) + +/* + * Various colorkey blit methods, for opaque and per-surface alpha + */ + +#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ + PIXEL_COPY(to, from, length, bpp) + +#ifdef MMX_ASMBLIT + +#define ALPHA_BLIT32_888MMX(to, from, length, bpp, alpha) \ + do { \ + Uint32 *srcp = (Uint32 *)(from); \ + Uint32 *dstp = (Uint32 *)(to); \ + int i = 0x00FF00FF; \ + movd_m2r(*(&i), mm3); \ + punpckldq_r2r(mm3, mm3); \ + i = 0xFF000000; \ + movd_m2r(*(&i), mm7); \ + punpckldq_r2r(mm7, mm7); \ + i = alpha | alpha << 16; \ + movd_m2r(*(&i), mm4); \ + punpckldq_r2r(mm4, mm4); \ + pcmpeqd_r2r(mm5,mm5); /* set mm5 to "1" */ \ + pxor_r2r(mm7, mm5); /* make clear alpha mask */ \ + i = length; \ + if(i & 1) { \ + movd_m2r((*srcp), mm1); /* src -> mm1 */ \ + punpcklbw_r2r(mm1, mm1); \ + pand_r2r(mm3, mm1); \ + movd_m2r((*dstp), mm2); /* dst -> mm2 */ \ + punpcklbw_r2r(mm2, mm2); \ + pand_r2r(mm3, mm2); \ + psubw_r2r(mm2, mm1); \ + pmullw_r2r(mm4, mm1); \ + psrlw_i2r(8, mm1); \ + paddw_r2r(mm1, mm2); \ + pand_r2r(mm3, mm2); \ + packuswb_r2r(mm2, mm2); \ + pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \ + movd_r2m(mm2, *dstp); \ + ++srcp; \ + ++dstp; \ + i--; \ + } \ + for(; i > 0; --i) { \ + movq_m2r((*srcp), mm0); \ + movq_r2r(mm0, mm1); \ + punpcklbw_r2r(mm0, mm0); \ + movq_m2r((*dstp), mm2); \ + punpckhbw_r2r(mm1, mm1); \ + movq_r2r(mm2, mm6); \ + pand_r2r(mm3, mm0); \ + punpcklbw_r2r(mm2, mm2); \ + pand_r2r(mm3, mm1); \ + punpckhbw_r2r(mm6, mm6); \ + pand_r2r(mm3, mm2); \ + psubw_r2r(mm2, mm0); \ + pmullw_r2r(mm4, mm0); \ + pand_r2r(mm3, mm6); \ + psubw_r2r(mm6, mm1); \ + pmullw_r2r(mm4, mm1); \ + psrlw_i2r(8, mm0); \ + paddw_r2r(mm0, mm2); \ + psrlw_i2r(8, mm1); \ + paddw_r2r(mm1, mm6); \ + pand_r2r(mm3, mm2); \ + pand_r2r(mm3, mm6); \ + packuswb_r2r(mm2, mm2); \ + packuswb_r2r(mm6, mm6); \ + psrlq_i2r(32, mm2); \ + psllq_i2r(32, mm6); \ + por_r2r(mm6, mm2); \ + pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \ + movq_r2m(mm2, *dstp); \ + srcp += 2; \ + dstp += 2; \ + i--; \ + } \ + emms(); \ + } while(0) + +#define ALPHA_BLIT16_565MMX(to, from, length, bpp, alpha) \ + do { \ + int i, n = 0; \ + Uint16 *srcp = (Uint16 *)(from); \ + Uint16 *dstp = (Uint16 *)(to); \ + Uint32 ALPHA = 0xF800; \ + movd_m2r(*(&ALPHA), mm1); \ + punpcklwd_r2r(mm1, mm1); \ + punpcklwd_r2r(mm1, mm1); \ + ALPHA = 0x07E0; \ + movd_m2r(*(&ALPHA), mm4); \ + punpcklwd_r2r(mm4, mm4); \ + punpcklwd_r2r(mm4, mm4); \ + ALPHA = 0x001F; \ + movd_m2r(*(&ALPHA), mm7); \ + punpcklwd_r2r(mm7, mm7); \ + punpcklwd_r2r(mm7, mm7); \ + alpha &= ~(1+2+4); \ + i = (Uint32)alpha | (Uint32)alpha << 16; \ + movd_m2r(*(&i), mm0); \ + punpckldq_r2r(mm0, mm0); \ + ALPHA = alpha >> 3; \ + i = ((int)(length) & 3); \ + for(; i > 0; --i) { \ + Uint32 s = *srcp++; \ + Uint32 d = *dstp; \ + s = (s | s << 16) & 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x07e0f81f; \ + *dstp++ = d | d >> 16; \ + n++; \ + } \ + i = (int)(length) - n; \ + for(; i > 0; --i) { \ + movq_m2r((*dstp), mm3); \ + movq_m2r((*srcp), mm2); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm1 , mm5); \ + psrlq_i2r(11, mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm1 , mm6); \ + psrlq_i2r(11, mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + psllq_i2r(11, mm6); \ + pand_r2r(mm1, mm6); \ + movq_r2r(mm4, mm5); \ + por_r2r(mm7, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm4 , mm5); \ + psrlq_i2r(5, mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm4 , mm6); \ + psrlq_i2r(5, mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + psllq_i2r(5, mm6); \ + pand_r2r(mm4, mm6); \ + movq_r2r(mm1, mm5); \ + por_r2r(mm7, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm7 , mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm7 , mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + pand_r2r(mm7, mm6); \ + movq_r2r(mm1, mm5); \ + por_r2r(mm4, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2m(mm3, *dstp); \ + srcp += 4; \ + dstp += 4; \ + i -= 3; \ + } \ + emms(); \ + } while(0) + +#define ALPHA_BLIT16_555MMX(to, from, length, bpp, alpha) \ + do { \ + int i, n = 0; \ + Uint16 *srcp = (Uint16 *)(from); \ + Uint16 *dstp = (Uint16 *)(to); \ + Uint32 ALPHA = 0x7C00; \ + movd_m2r(*(&ALPHA), mm1); \ + punpcklwd_r2r(mm1, mm1); \ + punpcklwd_r2r(mm1, mm1); \ + ALPHA = 0x03E0; \ + movd_m2r(*(&ALPHA), mm4); \ + punpcklwd_r2r(mm4, mm4); \ + punpcklwd_r2r(mm4, mm4); \ + ALPHA = 0x001F; \ + movd_m2r(*(&ALPHA), mm7); \ + punpcklwd_r2r(mm7, mm7); \ + punpcklwd_r2r(mm7, mm7); \ + alpha &= ~(1+2+4); \ + i = (Uint32)alpha | (Uint32)alpha << 16; \ + movd_m2r(*(&i), mm0); \ + punpckldq_r2r(mm0, mm0); \ + i = ((int)(length) & 3); \ + ALPHA = alpha >> 3; \ + for(; i > 0; --i) { \ + Uint32 s = *srcp++; \ + Uint32 d = *dstp; \ + s = (s | s << 16) & 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x03e07c1f; \ + *dstp++ = d | d >> 16; \ + n++; \ + } \ + i = (int)(length) - n; \ + for(; i > 0; --i) { \ + movq_m2r((*dstp), mm3); \ + movq_m2r((*srcp), mm2); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm1 , mm5); \ + psrlq_i2r(10, mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm1 , mm6); \ + psrlq_i2r(10, mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + psllq_i2r(10, mm6); \ + pand_r2r(mm1, mm6); \ + movq_r2r(mm4, mm5); \ + por_r2r(mm7, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm4 , mm5); \ + psrlq_i2r(5, mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm4 , mm6); \ + psrlq_i2r(5, mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + psllq_i2r(5, mm6); \ + pand_r2r(mm4, mm6); \ + movq_r2r(mm1, mm5); \ + por_r2r(mm7, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2r(mm2, mm5); \ + pand_r2r(mm7 , mm5); \ + movq_r2r(mm3, mm6); \ + pand_r2r(mm7 , mm6); \ + psubw_r2r(mm6, mm5); \ + pmullw_r2r(mm0, mm5); \ + psrlw_i2r(8, mm5); \ + paddw_r2r(mm5, mm6); \ + pand_r2r(mm7, mm6); \ + movq_r2r(mm1, mm5); \ + por_r2r(mm4, mm5); \ + pand_r2r(mm5, mm3); \ + por_r2r(mm6, mm3); \ + movq_r2m(mm3, *dstp); \ + srcp += 4; \ + dstp += 4; \ + i -= 3; \ + } \ + emms(); \ + } while(0) + +#endif + +/* + * For 32bpp pixels on the form 0x00rrggbb: + * If we treat the middle component separately, we can process the two + * remaining in parallel. This is safe to do because of the gap to the left + * of each component, so the bits from the multiplication don't collide. + * This can be used for any RGB permutation of course. + */ +#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + *dst++ = d1 | d; \ + } \ + } while(0) + +/* + * For 16bpp pixels we can go a step further: put the middle component + * in the high 16 bits of a 32 bit word, and process all three RGB + * components at the same time. Since the smallest gap is here just + * 5 bits, we have to scale alpha down to 5 bits as well. + */ +#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + Uint32 ALPHA = alpha >> 3; \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x07e0f81f; \ + *dst++ = (Uint16)(d | d >> 16); \ + } \ + } while(0) + +#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + Uint32 ALPHA = alpha >> 3; \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x03e07c1f; \ + *dst++ = (Uint16)(d | d >> 16); \ + } \ + } while(0) + +/* + * The general slow catch-all function, for remaining depths and formats + */ +#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint8 *src = from; \ + Uint8 *dst = to; \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s, d; \ + unsigned rs, gs, bs, rd, gd, bd; \ + switch(bpp) { \ + case 2: \ + s = *(Uint16 *)src; \ + d = *(Uint16 *)dst; \ + break; \ + case 3: \ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + s = (src[0] << 16) | (src[1] << 8) | src[2]; \ + d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ + } else { \ + s = (src[2] << 16) | (src[1] << 8) | src[0]; \ + d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ + } \ + break; \ + case 4: \ + s = *(Uint32 *)src; \ + d = *(Uint32 *)dst; \ + break; \ + } \ + RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ + RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ + rd += (rs - rd) * alpha >> 8; \ + gd += (gs - gd) * alpha >> 8; \ + bd += (bs - bd) * alpha >> 8; \ + PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ + switch(bpp) { \ + case 2: \ + *(Uint16 *)dst = (Uint16)d; \ + break; \ + case 3: \ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + dst[0] = (Uint8)(d >> 16); \ + dst[1] = (Uint8)(d >> 8); \ + dst[2] = (Uint8)(d); \ + } else { \ + dst[0] = (Uint8)d; \ + dst[1] = (Uint8)(d >> 8); \ + dst[2] = (Uint8)(d >> 16); \ + } \ + break; \ + case 4: \ + *(Uint32 *)dst = d; \ + break; \ + } \ + src += bpp; \ + dst += bpp; \ + } \ + } while(0) + +#ifdef MMX_ASMBLIT + +#define ALPHA_BLIT32_888_50MMX(to, from, length, bpp, alpha) \ + do { \ + Uint32 *srcp = (Uint32 *)(from); \ + Uint32 *dstp = (Uint32 *)(to); \ + int i = 0x00fefefe; \ + movd_m2r(*(&i), mm4); \ + punpckldq_r2r(mm4, mm4); \ + i = 0x00010101; \ + movd_m2r(*(&i), mm3); \ + punpckldq_r2r(mm3, mm3); \ + i = (int)(length); \ + if( i & 1 ) { \ + Uint32 s = *srcp++; \ + Uint32 d = *dstp; \ + *dstp++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ + + (s & d & 0x00010101); \ + i--; \ + } \ + for(; i > 0; --i) { \ + movq_m2r((*dstp), mm2); /* dst -> mm2 */ \ + movq_r2r(mm2, mm6); /* dst -> mm6 */ \ + movq_m2r((*srcp), mm1); /* src -> mm1 */ \ + movq_r2r(mm1, mm5); /* src -> mm5 */ \ + pand_r2r(mm4, mm6); /* dst & 0x00fefefe -> mm6 */ \ + pand_r2r(mm4, mm5); /* src & 0x00fefefe -> mm5 */ \ + paddd_r2r(mm6, mm5); /* (dst & 0x00fefefe) + (dst & 0x00fefefe) -> mm5 */ \ + psrld_i2r(1, mm5); \ + pand_r2r(mm1, mm2); /* s & d -> mm2 */ \ + pand_r2r(mm3, mm2); /* s & d & 0x00010101 -> mm2 */ \ + paddd_r2r(mm5, mm2); \ + movq_r2m(mm2, (*dstp)); \ + dstp += 2; \ + srcp += 2; \ + i--; \ + } \ + emms(); \ + } while(0) + +#endif + +/* + * Special case: 50% alpha (alpha=128) + * This is treated specially because it can be optimized very well, and + * since it is good for many cases of semi-translucency. + * The theory is to do all three components at the same time: + * First zero the lowest bit of each component, which gives us room to + * add them. Then shift right and add the sum of the lowest bits. + */ +#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ + + (s & d & 0x00010101); \ + } \ + } while(0) + +/* + * For 16bpp, we can actually blend two pixels in parallel, if we take + * care to shift before we add, not after. + */ + +/* helper: blend a single 16 bit pixel at 50% */ +#define BLEND16_50(dst, src, mask) \ + do { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \ + (s & d & (~mask & 0xffff))); \ + } while(0) + +/* basic 16bpp blender. mask is the pixels to keep when adding. */ +#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ + do { \ + unsigned n = (length); \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + if(((uintptr_t)src ^ (uintptr_t)dst) & 3) { \ + /* source and destination not in phase, blit one by one */ \ + while(n--) \ + BLEND16_50(dst, src, mask); \ + } else { \ + if((uintptr_t)src & 3) { \ + /* first odd pixel */ \ + BLEND16_50(dst, src, mask); \ + n--; \ + } \ + for(; n > 1; n -= 2) { \ + Uint32 s = *(Uint32 *)src; \ + Uint32 d = *(Uint32 *)dst; \ + *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ + + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16))); \ + src += 2; \ + dst += 2; \ + } \ + if(n) \ + BLEND16_50(dst, src, mask); /* last odd pixel */ \ + } \ + } while(0) + +#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ + ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de) + +#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ + ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde) + +#ifdef MMX_ASMBLIT + +#define CHOOSE_BLIT(blitter, alpha, fmt) \ + do { \ + if(alpha == 255) { \ + switch(fmt->BytesPerPixel) { \ + case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ + case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ + case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ + case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ + } \ + } else { \ + switch(fmt->BytesPerPixel) { \ + case 1: \ + /* No 8bpp alpha blitting */ \ + break; \ + \ + case 2: \ + switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ + case 0xffff: \ + if(fmt->Gmask == 0x07e0 \ + || fmt->Rmask == 0x07e0 \ + || fmt->Bmask == 0x07e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_565_50); \ + else { \ + if(SDL_HasMMX()) \ + blitter(2, Uint8, ALPHA_BLIT16_565MMX); \ + else \ + blitter(2, Uint8, ALPHA_BLIT16_565); \ + } \ + } else \ + goto general16; \ + break; \ + \ + case 0x7fff: \ + if(fmt->Gmask == 0x03e0 \ + || fmt->Rmask == 0x03e0 \ + || fmt->Bmask == 0x03e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_555_50); \ + else { \ + if(SDL_HasMMX()) \ + blitter(2, Uint8, ALPHA_BLIT16_555MMX); \ + else \ + blitter(2, Uint8, ALPHA_BLIT16_555); \ + } \ + break; \ + } \ + /* fallthrough */ \ + \ + default: \ + general16: \ + blitter(2, Uint8, ALPHA_BLIT_ANY); \ + } \ + break; \ + \ + case 3: \ + blitter(3, Uint8, ALPHA_BLIT_ANY); \ + break; \ + \ + case 4: \ + if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ + && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ + || fmt->Bmask == 0xff00)) { \ + if(alpha == 128) \ + { \ + if(SDL_HasMMX()) \ + blitter(4, Uint16, ALPHA_BLIT32_888_50MMX);\ + else \ + blitter(4, Uint16, ALPHA_BLIT32_888_50);\ + } \ + else \ + { \ + if(SDL_HasMMX()) \ + blitter(4, Uint16, ALPHA_BLIT32_888MMX);\ + else \ + blitter(4, Uint16, ALPHA_BLIT32_888); \ + } \ + } else \ + blitter(4, Uint16, ALPHA_BLIT_ANY); \ + break; \ + } \ + } \ + } while(0) + +#else + +#define CHOOSE_BLIT(blitter, alpha, fmt) \ + do { \ + if(alpha == 255) { \ + switch(fmt->BytesPerPixel) { \ + case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ + case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ + case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ + case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ + } \ + } else { \ + switch(fmt->BytesPerPixel) { \ + case 1: \ + /* No 8bpp alpha blitting */ \ + break; \ + \ + case 2: \ + switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ + case 0xffff: \ + if(fmt->Gmask == 0x07e0 \ + || fmt->Rmask == 0x07e0 \ + || fmt->Bmask == 0x07e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_565_50); \ + else { \ + blitter(2, Uint8, ALPHA_BLIT16_565); \ + } \ + } else \ + goto general16; \ + break; \ + \ + case 0x7fff: \ + if(fmt->Gmask == 0x03e0 \ + || fmt->Rmask == 0x03e0 \ + || fmt->Bmask == 0x03e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_555_50); \ + else { \ + blitter(2, Uint8, ALPHA_BLIT16_555); \ + } \ + break; \ + } \ + /* fallthrough */ \ + \ + default: \ + general16: \ + blitter(2, Uint8, ALPHA_BLIT_ANY); \ + } \ + break; \ + \ + case 3: \ + blitter(3, Uint8, ALPHA_BLIT_ANY); \ + break; \ + \ + case 4: \ + if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ + && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ + || fmt->Bmask == 0xff00)) { \ + if(alpha == 128) \ + blitter(4, Uint16, ALPHA_BLIT32_888_50); \ + else \ + blitter(4, Uint16, ALPHA_BLIT32_888); \ + } else \ + blitter(4, Uint16, ALPHA_BLIT_ANY); \ + break; \ + } \ + } \ + } while(0) + +#endif + +/* + * This takes care of the case when the surface is clipped on the left and/or + * right. Top clipping has already been taken care of. + */ +static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, + Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha) +{ + SDL_PixelFormat *fmt = dst->format; + +#define RLECLIPBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * bpp; \ + for(;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if(run) { \ + /* clip to left and right borders */ \ + if(ofs < right) { \ + int start = 0; \ + int len = run; \ + int startcol; \ + if(left - ofs > 0) { \ + start = left - ofs; \ + len -= start; \ + if(len <= 0) \ + goto nocopy ## bpp ## do_blit; \ + } \ + startcol = ofs + start; \ + if(len > right - startcol) \ + len = right - startcol; \ + do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ + len, bpp, alpha); \ + } \ + nocopy ## bpp ## do_blit: \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + break; \ + if(ofs == w) { \ + ofs = 0; \ + dstbuf += dst->pitch; \ + if(!--linecount) \ + break; \ + } \ + } \ + } while(0) + + CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); + +#undef RLECLIPBLIT + +} + + +/* blit a colorkeyed RLE surface */ +int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + Uint8 *dstbuf; + Uint8 *srcbuf; + int x, y; + int w = src->w; + unsigned alpha; + + /* Lock the destination if necessary */ + if ( SDL_MUSTLOCK(dst) ) { + if ( SDL_LockSurface(dst) < 0 ) { + return(-1); + } + } + + /* Set up the source and destination pointers */ + x = dstrect->x; + y = dstrect->y; + dstbuf = (Uint8 *)dst->pixels + + y * dst->pitch + x * src->format->BytesPerPixel; + srcbuf = (Uint8 *)src->map->sw_data->aux_data; + + { + /* skip lines at the top if neccessary */ + int vskip = srcrect->y; + int ofs = 0; + if(vskip) { + +#define RLESKIP(bpp, Type) \ + for(;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += sizeof(Type) * 2; \ + if(run) { \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + goto done; \ + if(ofs == w) { \ + ofs = 0; \ + if(!--vskip) \ + break; \ + } \ + } + + switch(src->format->BytesPerPixel) { + case 1: RLESKIP(1, Uint8); break; + case 2: RLESKIP(2, Uint8); break; + case 3: RLESKIP(3, Uint8); break; + case 4: RLESKIP(4, Uint16); break; + } + +#undef RLESKIP + + } + } + + alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA + ? src->format->alpha : 255; + /* if left or right edge clipping needed, call clip blit */ + if ( srcrect->x || srcrect->w != src->w ) { + RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); + } else { + SDL_PixelFormat *fmt = src->format; + +#define RLEBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + for(;;) { \ + unsigned run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if(run) { \ + do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + break; \ + if(ofs == w) { \ + ofs = 0; \ + dstbuf += dst->pitch; \ + if(!--linecount) \ + break; \ + } \ + } \ + } while(0) + + CHOOSE_BLIT(RLEBLIT, alpha, fmt); + +#undef RLEBLIT + } + +done: + /* Unlock the destination if necessary */ + if ( SDL_MUSTLOCK(dst) ) { + SDL_UnlockSurface(dst); + } + return(0); +} + +#undef OPAQUE_BLIT + +/* + * Per-pixel blitting macros for translucent pixels: + * These use the same techniques as the per-surface blitting macros + */ + +/* + * For 32bpp pixels, we have made sure the alpha is stored in the top + * 8 bits, so proceed as usual + */ +#define BLIT_TRANSL_888(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = s >> 24; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + dst = d1 | d; \ + } while(0) + +/* + * For 16bpp pixels, we have stored the 5 most significant alpha bits in + * bits 5-10. As before, we can process all 3 RGB components at the same time. + */ +#define BLIT_TRANSL_565(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x07e0f81f; \ + dst = (Uint16)(d | d >> 16); \ + } while(0) + +#define BLIT_TRANSL_555(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x03e07c1f; \ + dst = (Uint16)(d | d >> 16); \ + } while(0) + +/* used to save the destination format in the encoding. Designed to be + macro-compatible with SDL_PixelFormat but without the unneeded fields */ +typedef struct { + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; +} RLEDestFormat; + +/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ +static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, + Uint8 *dstbuf, SDL_Rect *srcrect) +{ + SDL_PixelFormat *df = dst->format; + /* + * clipped blitter: Ptype is the destination pixel type, + * Ctype the translucent count type, and do_blend the macro + * to blend one pixel. + */ +#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * sizeof(Ptype); \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if(run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if(left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if(crun > right - cofs) \ + crun = right - cofs; \ + if(crun > 0) \ + PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ + srcbuf + (cofs - ofs) * sizeof(Ptype), \ + (unsigned)crun, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if(!ofs) \ + return; \ + } while(ofs < w); \ + /* skip padding if necessary */ \ + if(sizeof(Ptype) == 2) \ + srcbuf += (uintptr_t)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if(run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if(left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if(crun > right - cofs) \ + crun = right - cofs; \ + if(crun > 0) { \ + Ptype *dst = (Ptype *)dstbuf + cofs; \ + Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ + int i; \ + for(i = 0; i < crun; i++) \ + do_blend(src[i], dst[i]); \ + } \ + srcbuf += run * 4; \ + ofs += run; \ + } \ + } while(ofs < w); \ + dstbuf += dst->pitch; \ + } while(--linecount); \ + } while(0) + + switch(df->BytesPerPixel) { + case 2: + if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 + || df->Bmask == 0x07e0) + RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); + else + RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); + break; + case 4: + RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); + break; + } +} + +/* blit a pixel-alpha RLE surface */ +int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int x, y; + int w = src->w; + Uint8 *srcbuf, *dstbuf; + SDL_PixelFormat *df = dst->format; + + /* Lock the destination if necessary */ + if ( SDL_MUSTLOCK(dst) ) { + if ( SDL_LockSurface(dst) < 0 ) { + return -1; + } + } + + x = dstrect->x; + y = dstrect->y; + dstbuf = (Uint8 *)dst->pixels + + y * dst->pitch + x * df->BytesPerPixel; + srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat); + + { + /* skip lines at the top if necessary */ + int vskip = srcrect->y; + if(vskip) { + int ofs; + if(df->BytesPerPixel == 2) { + /* the 16/32 interleaved format */ + do { + /* skip opaque line */ + ofs = 0; + do { + int run; + ofs += srcbuf[0]; + run = srcbuf[1]; + srcbuf += 2; + if(run) { + srcbuf += 2 * run; + ofs += run; + } else if(!ofs) + goto done; + } while(ofs < w); + + /* skip padding */ + srcbuf += (uintptr_t)srcbuf & 2; + + /* skip translucent line */ + ofs = 0; + do { + int run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4 * (run + 1); + ofs += run; + } while(ofs < w); + } while(--vskip); + } else { + /* the 32/32 interleaved format */ + vskip <<= 1; /* opaque and translucent have same format */ + do { + ofs = 0; + do { + int run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + if(run) { + srcbuf += 4 * run; + ofs += run; + } else if(!ofs) + goto done; + } while(ofs < w); + } while(--vskip); + } + } + } + + /* if left or right edge clipping needed, call clip blit */ + if(srcrect->x || srcrect->w != src->w) { + RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect); + } else { + + /* + * non-clipped blitter. Ptype is the destination pixel type, + * Ctype the translucent count type, and do_blend the + * macro to blend one pixel. + */ +#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if(run) { \ + PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ + run, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if(!ofs) \ + goto done; \ + } while(ofs < w); \ + /* skip padding if necessary */ \ + if(sizeof(Ptype) == 2) \ + srcbuf += (uintptr_t)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if(run) { \ + Ptype *dst = (Ptype *)dstbuf + ofs; \ + unsigned i; \ + for(i = 0; i < run; i++) { \ + Uint32 src = *(Uint32 *)srcbuf; \ + do_blend(src, *dst); \ + srcbuf += 4; \ + dst++; \ + } \ + ofs += run; \ + } \ + } while(ofs < w); \ + dstbuf += dst->pitch; \ + } while(--linecount); \ + } while(0) + + switch(df->BytesPerPixel) { + case 2: + if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 + || df->Bmask == 0x07e0) + RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); + else + RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); + break; + case 4: + RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); + break; + } + } + + done: + /* Unlock the destination if necessary */ + if ( SDL_MUSTLOCK(dst) ) { + SDL_UnlockSurface(dst); + } + return 0; +} + +/* + * Auxiliary functions: + * The encoding functions take 32bpp rgb + a, and + * return the number of bytes copied to the destination. + * The decoding functions copy to 32bpp rgb + a, and + * return the number of bytes copied from the source. + * These are only used in the encoder and un-RLE code and are therefore not + * highly optimised. + */ + +/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ +static int copy_opaque_16(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint16 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b; + RGB_FROM_PIXEL(*src, sfmt, r, g, b); + PIXEL_FROM_RGB(*d, dfmt, r, g, b); + src++; + d++; + } + return n * 2; +} + +/* decode opaque pixels from 16bpp to 32bpp rgb + a */ +static int uncopy_opaque_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint16 *s = src; + unsigned alpha = dfmt->Amask ? 255 : 0; + for(i = 0; i < n; i++) { + unsigned r, g, b; + RGB_FROM_PIXEL(*s, sfmt, r, g, b); + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha); + s++; + dst++; + } + return n * 2; +} + + + +/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ +static int copy_transl_565(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint16 pix; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pix, dfmt, r, g, b); + *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0); + src++; + d++; + } + return n * 4; +} + +/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ +static int copy_transl_555(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint16 pix; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pix, dfmt, r, g, b); + *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0); + src++; + d++; + } + return n * 4; +} + +/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ +static int uncopy_transl_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *s = src; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pix = *s++; + a = (pix & 0x3e0) >> 2; + pix = (pix & ~0x3e0) | pix >> 16; + RGB_FROM_PIXEL(pix, sfmt, r, g, b); + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); + dst++; + } + return n * 4; +} + +/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ +static int copy_32(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pixel; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pixel, dfmt, r, g, b); + *d++ = pixel | a << 24; + src++; + } + return n * 4; +} + +/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ +static int uncopy_32(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *s = src; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pixel = *s++; + RGB_FROM_PIXEL(pixel, sfmt, r, g, b); + a = pixel >> 24; + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); + dst++; + } + return n * 4; +} + +#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) + +#define ISTRANSL(pixel, fmt) \ + ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) + +/* convert surface to be quickly alpha-blittable onto dest, if possible */ +static int RLEAlphaSurface(SDL_Surface *surface) +{ + SDL_Surface *dest; + SDL_PixelFormat *df; + int maxsize = 0; + int max_opaque_run; + int max_transl_run = 65535; + unsigned masksum; + Uint8 *rlebuf, *dst; + int (*copy_opaque)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); + int (*copy_transl)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); + + dest = surface->map->dst; + if(!dest) + return -1; + df = dest->format; + if(surface->format->BitsPerPixel != 32) + return -1; /* only 32bpp source supported */ + + /* find out whether the destination is one we support, + and determine the max size of the encoded result */ + masksum = df->Rmask | df->Gmask | df->Bmask; + switch(df->BytesPerPixel) { + case 2: + /* 16bpp: only support 565 and 555 formats */ + switch(masksum) { + case 0xffff: + if(df->Gmask == 0x07e0 + || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { + copy_opaque = copy_opaque_16; + copy_transl = copy_transl_565; + } else + return -1; + break; + case 0x7fff: + if(df->Gmask == 0x03e0 + || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { + copy_opaque = copy_opaque_16; + copy_transl = copy_transl_555; + } else + return -1; + break; + default: + return -1; + } + max_opaque_run = 255; /* runs stored as bytes */ + + /* worst case is alternating opaque and translucent pixels, + with room for alignment padding between lines */ + maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; + break; + case 4: + if(masksum != 0x00ffffff) + return -1; /* requires unused high byte */ + copy_opaque = copy_32; + copy_transl = copy_32; + max_opaque_run = 255; /* runs stored as short ints */ + + /* worst case is alternating opaque and translucent pixels */ + maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; + break; + default: + return -1; /* anything else unsupported right now */ + } + + maxsize += sizeof(RLEDestFormat); + rlebuf = (Uint8 *)SDL_malloc(maxsize); + if(!rlebuf) { + SDL_OutOfMemory(); + return -1; + } + { + /* save the destination format so we can undo the encoding later */ + RLEDestFormat *r = (RLEDestFormat *)rlebuf; + r->BytesPerPixel = df->BytesPerPixel; + r->Rloss = df->Rloss; + r->Gloss = df->Gloss; + r->Bloss = df->Bloss; + r->Rshift = df->Rshift; + r->Gshift = df->Gshift; + r->Bshift = df->Bshift; + r->Ashift = df->Ashift; + r->Rmask = df->Rmask; + r->Gmask = df->Gmask; + r->Bmask = df->Bmask; + r->Amask = df->Amask; + } + dst = rlebuf + sizeof(RLEDestFormat); + + /* Do the actual encoding */ + { + int x, y; + int h = surface->h, w = surface->w; + SDL_PixelFormat *sf = surface->format; + Uint32 *src = (Uint32 *)surface->pixels; + Uint8 *lastline = dst; /* end of last non-blank line */ + + /* opaque counts are 8 or 16 bits, depending on target depth */ +#define ADD_OPAQUE_COUNTS(n, m) \ + if(df->BytesPerPixel == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ + dst += 4; \ + } else { \ + dst[0] = n; \ + dst[1] = m; \ + dst += 2; \ + } + + /* translucent counts are always 16 bit */ +#define ADD_TRANSL_COUNTS(n, m) \ + (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) + + for(y = 0; y < h; y++) { + int runstart, skipstart; + int blankline = 0; + /* First encode all opaque pixels of a scan line */ + x = 0; + do { + int run, skip, len; + skipstart = x; + while(x < w && !ISOPAQUE(src[x], sf)) + x++; + runstart = x; + while(x < w && ISOPAQUE(src[x], sf)) + x++; + skip = runstart - skipstart; + if(skip == w) + blankline = 1; + run = x - runstart; + while(skip > max_opaque_run) { + ADD_OPAQUE_COUNTS(max_opaque_run, 0); + skip -= max_opaque_run; + } + len = MIN(run, max_opaque_run); + ADD_OPAQUE_COUNTS(skip, len); + dst += copy_opaque(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + while(run) { + len = MIN(run, max_opaque_run); + ADD_OPAQUE_COUNTS(0, len); + dst += copy_opaque(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + } + } while(x < w); + + /* Make sure the next output address is 32-bit aligned */ + dst += (uintptr_t)dst & 2; + + /* Next, encode all translucent pixels of the same scan line */ + x = 0; + do { + int run, skip, len; + skipstart = x; + while(x < w && !ISTRANSL(src[x], sf)) + x++; + runstart = x; + while(x < w && ISTRANSL(src[x], sf)) + x++; + skip = runstart - skipstart; + blankline &= (skip == w); + run = x - runstart; + while(skip > max_transl_run) { + ADD_TRANSL_COUNTS(max_transl_run, 0); + skip -= max_transl_run; + } + len = MIN(run, max_transl_run); + ADD_TRANSL_COUNTS(skip, len); + dst += copy_transl(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + while(run) { + len = MIN(run, max_transl_run); + ADD_TRANSL_COUNTS(0, len); + dst += copy_transl(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + } + if(!blankline) + lastline = dst; + } while(x < w); + + src += surface->pitch >> 2; + } + dst = lastline; /* back up past trailing blank lines */ + ADD_OPAQUE_COUNTS(0, 0); + } + +#undef ADD_OPAQUE_COUNTS +#undef ADD_TRANSL_COUNTS + + /* Now that we have it encoded, release the original pixels */ + if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + SDL_free( surface->pixels ); + surface->pixels = NULL; + } + + /* realloc the buffer to release unused memory */ + { + Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); + if(!p) + p = rlebuf; + surface->map->sw_data->aux_data = p; + } + + return 0; +} + +static Uint32 getpix_8(Uint8 *srcbuf) +{ + return *srcbuf; +} + +static Uint32 getpix_16(Uint8 *srcbuf) +{ + return *(Uint16 *)srcbuf; +} + +static Uint32 getpix_24(Uint8 *srcbuf) +{ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); +#else + return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2]; +#endif +} + +static Uint32 getpix_32(Uint8 *srcbuf) +{ + return *(Uint32 *)srcbuf; +} + +typedef Uint32 (*getpix_func)(Uint8 *); + +static getpix_func getpixes[4] = { + getpix_8, getpix_16, getpix_24, getpix_32 +}; + +static int RLEColorkeySurface(SDL_Surface *surface) +{ + Uint8 *rlebuf, *dst; + int maxn; + int y; + Uint8 *srcbuf, *lastline; + int maxsize = 0; + int bpp = surface->format->BytesPerPixel; + getpix_func getpix; + Uint32 ckey, rgbmask; + int w, h; + + /* calculate the worst case size for the compressed surface */ + switch(bpp) { + case 1: + /* worst case is alternating opaque and transparent pixels, + starting with an opaque pixel */ + maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2; + break; + case 2: + case 3: + /* worst case is solid runs, at most 255 pixels wide */ + maxsize = surface->h * (2 * (surface->w / 255 + 1) + + surface->w * bpp) + 2; + break; + case 4: + /* worst case is solid runs, at most 65535 pixels wide */ + maxsize = surface->h * (4 * (surface->w / 65535 + 1) + + surface->w * 4) + 4; + break; + } + + rlebuf = (Uint8 *)SDL_malloc(maxsize); + if ( rlebuf == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + + /* Set up the conversion */ + srcbuf = (Uint8 *)surface->pixels; + maxn = bpp == 4 ? 65535 : 255; + dst = rlebuf; + rgbmask = ~surface->format->Amask; + ckey = surface->format->colorkey & rgbmask; + lastline = dst; + getpix = getpixes[bpp - 1]; + w = surface->w; + h = surface->h; + +#define ADD_COUNTS(n, m) \ + if(bpp == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ + dst += 4; \ + } else { \ + dst[0] = n; \ + dst[1] = m; \ + dst += 2; \ + } + + for(y = 0; y < h; y++) { + int x = 0; + int blankline = 0; + do { + int run, skip, len; + int runstart; + int skipstart = x; + + /* find run of transparent, then opaque pixels */ + while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) + x++; + runstart = x; + while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) + x++; + skip = runstart - skipstart; + if(skip == w) + blankline = 1; + run = x - runstart; + + /* encode segment */ + while(skip > maxn) { + ADD_COUNTS(maxn, 0); + skip -= maxn; + } + len = MIN(run, maxn); + ADD_COUNTS(skip, len); + SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); + dst += len * bpp; + run -= len; + runstart += len; + while(run) { + len = MIN(run, maxn); + ADD_COUNTS(0, len); + SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); + dst += len * bpp; + runstart += len; + run -= len; + } + if(!blankline) + lastline = dst; + } while(x < w); + + srcbuf += surface->pitch; + } + dst = lastline; /* back up bast trailing blank lines */ + ADD_COUNTS(0, 0); + +#undef ADD_COUNTS + + /* Now that we have it encoded, release the original pixels */ + if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + SDL_free( surface->pixels ); + surface->pixels = NULL; + } + + /* realloc the buffer to release unused memory */ + { + /* If realloc returns NULL, the original block is left intact */ + Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); + if(!p) + p = rlebuf; + surface->map->sw_data->aux_data = p; + } + + return(0); +} + +int SDL_RLESurface(SDL_Surface *surface) +{ + int retcode; + + /* Clear any previous RLE conversion */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + + /* We don't support RLE encoding of bitmaps */ + if ( surface->format->BitsPerPixel < 8 ) { + return(-1); + } + + /* Lock the surface if it's in hardware */ + if ( SDL_MUSTLOCK(surface) ) { + if ( SDL_LockSurface(surface) < 0 ) { + return(-1); + } + } + + /* Encode */ + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + retcode = RLEColorkeySurface(surface); + } else { + if((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA + && surface->format->Amask != 0) + retcode = RLEAlphaSurface(surface); + else + retcode = -1; /* no RLE for per-surface alpha sans ckey */ + } + + /* Unlock the surface if it's in hardware */ + if ( SDL_MUSTLOCK(surface) ) { + SDL_UnlockSurface(surface); + } + + if(retcode < 0) + return -1; + + /* The surface is now accelerated */ + surface->flags |= SDL_RLEACCEL; + + return(0); +} + +/* + * Un-RLE a surface with pixel alpha + * This may not give back exactly the image before RLE-encoding; all + * completely transparent pixels will be lost, and colour and alpha depth + * may have been reduced (when encoding for 16bpp targets). + */ +static SDL_bool UnRLEAlpha(SDL_Surface *surface) +{ + Uint8 *srcbuf; + Uint32 *dst; + SDL_PixelFormat *sf = surface->format; + RLEDestFormat *df = surface->map->sw_data->aux_data; + int (*uncopy_opaque)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); + int (*uncopy_transl)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); + int w = surface->w; + int bpp = df->BytesPerPixel; + + if(bpp == 2) { + uncopy_opaque = uncopy_opaque_16; + uncopy_transl = uncopy_transl_16; + } else { + uncopy_opaque = uncopy_transl = uncopy_32; + } + + surface->pixels = SDL_malloc(surface->h * surface->pitch); + if ( !surface->pixels ) { + return(SDL_FALSE); + } + /* fill background with transparent pixels */ + SDL_memset(surface->pixels, 0, surface->h * surface->pitch); + + dst = surface->pixels; + srcbuf = (Uint8 *)(df + 1); + for(;;) { + /* copy opaque pixels */ + int ofs = 0; + do { + unsigned run; + if(bpp == 2) { + ofs += srcbuf[0]; + run = srcbuf[1]; + srcbuf += 2; + } else { + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + } + if(run) { + srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf); + ofs += run; + } else if(!ofs) + return(SDL_TRUE); + } while(ofs < w); + + /* skip padding if needed */ + if(bpp == 2) + srcbuf += (uintptr_t)srcbuf & 2; + + /* copy translucent pixels */ + ofs = 0; + do { + unsigned run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + if(run) { + srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); + ofs += run; + } + } while(ofs < w); + dst += surface->pitch >> 2; + } + /* Make the compiler happy */ + return(SDL_TRUE); +} + +void SDL_UnRLESurface(SDL_Surface *surface, int recode) +{ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + surface->flags &= ~SDL_RLEACCEL; + + if(recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + SDL_Rect full; + unsigned alpha_flag; + + /* re-create the original surface */ + surface->pixels = SDL_malloc(surface->h * surface->pitch); + if ( !surface->pixels ) { + /* Oh crap... */ + surface->flags |= SDL_RLEACCEL; + return; + } + + /* fill it with the background colour */ + SDL_FillRect(surface, NULL, surface->format->colorkey); + + /* now render the encoded surface */ + full.x = full.y = 0; + full.w = surface->w; + full.h = surface->h; + alpha_flag = surface->flags & SDL_SRCALPHA; + surface->flags &= ~SDL_SRCALPHA; /* opaque blit */ + SDL_RLEBlit(surface, &full, surface, &full); + surface->flags |= alpha_flag; + } else { + if ( !UnRLEAlpha(surface) ) { + /* Oh crap... */ + surface->flags |= SDL_RLEACCEL; + return; + } + } + } + + if ( surface->map && surface->map->sw_data->aux_data ) { + SDL_free(surface->map->sw_data->aux_data); + surface->map->sw_data->aux_data = NULL; + } + } +} + + diff --git a/apps/plugins/sdl/src/video/SDL_RLEaccel_c.h b/apps/plugins/sdl/src/video/SDL_RLEaccel_c.h new file mode 100644 index 0000000000..daf0c53f2d --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_RLEaccel_c.h @@ -0,0 +1,31 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Useful functions and variables from SDL_RLEaccel.c */ + +extern int SDL_RLESurface(SDL_Surface *surface); +extern int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +extern int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +extern void SDL_UnRLESurface(SDL_Surface *surface, int recode); diff --git a/apps/plugins/sdl/src/video/SDL_blit.c b/apps/plugins/sdl/src/video/SDL_blit.c new file mode 100644 index 0000000000..e3f194aee4 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit.c @@ -0,0 +1,360 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_RLEaccel_c.h" +#include "SDL_pixels_c.h" + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES +#define MMX_ASMBLIT +#if (__GNUC__ > 2) /* SSE instructions aren't in GCC 2. */ +#define SSE_ASMBLIT +#endif +#endif + +#if defined(MMX_ASMBLIT) +#include "SDL_cpuinfo.h" +#include "mmx.h" +#endif + +/* The general purpose software blit routine */ +static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int okay; + int src_locked; + int dst_locked; + + /* Everything is okay at the beginning... */ + okay = 1; + + /* Lock the destination if it's in hardware */ + dst_locked = 0; + if ( SDL_MUSTLOCK(dst) ) { + if ( SDL_LockSurface(dst) < 0 ) { + okay = 0; + } else { + dst_locked = 1; + } + } + /* Lock the source if it's in hardware */ + src_locked = 0; + if ( SDL_MUSTLOCK(src) ) { + if ( SDL_LockSurface(src) < 0 ) { + okay = 0; + } else { + src_locked = 1; + } + } + + /* Set up source and destination buffer pointers, and BLIT! */ + if ( okay && srcrect->w && srcrect->h ) { + SDL_BlitInfo info; + SDL_loblit RunBlit; + + /* Set up the blit information */ + info.s_pixels = (Uint8 *)src->pixels + + (Uint16)srcrect->y*src->pitch + + (Uint16)srcrect->x*src->format->BytesPerPixel; + info.s_width = srcrect->w; + info.s_height = srcrect->h; + info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel; + info.d_pixels = (Uint8 *)dst->pixels + + (Uint16)dstrect->y*dst->pitch + + (Uint16)dstrect->x*dst->format->BytesPerPixel; + info.d_width = dstrect->w; + info.d_height = dstrect->h; + info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel; + info.aux_data = src->map->sw_data->aux_data; + info.src = src->format; + info.table = src->map->table; + info.dst = dst->format; + RunBlit = src->map->sw_data->blit; + + /* Run the actual software blit */ + RunBlit(&info); + } + + /* We need to unlock the surfaces if they're locked */ + if ( dst_locked ) { + SDL_UnlockSurface(dst); + } + if ( src_locked ) { + SDL_UnlockSurface(src); + } + /* Blit is done! */ + return(okay ? 0 : -1); +} + +#ifdef MMX_ASMBLIT +static __inline__ void SDL_memcpyMMX(Uint8 *to, const Uint8 *from, int len) +{ + int i; + + for(i=0; id_width*info->dst->BytesPerPixel; + h = info->d_height; + src = info->s_pixels; + dst = info->d_pixels; + srcskip = w+info->s_skip; + dstskip = w+info->d_skip; + +#ifdef SSE_ASMBLIT + if(SDL_HasSSE()) + { + while ( h-- ) { + SDL_memcpySSE(dst, src, w); + src += srcskip; + dst += dstskip; + } + __asm__ __volatile__ ( + " emms\n" + ::); + } + else +#endif +#ifdef MMX_ASMBLIT + if(SDL_HasMMX()) + { + while ( h-- ) { + SDL_memcpyMMX(dst, src, w); + src += srcskip; + dst += dstskip; + } + __asm__ __volatile__ ( + " emms\n" + ::); + } + else +#endif + while ( h-- ) { + SDL_memcpy(dst, src, w); + src += srcskip; + dst += dstskip; + } +} + +static void SDL_BlitCopyOverlap(SDL_BlitInfo *info) +{ + Uint8 *src, *dst; + int w, h; + int srcskip, dstskip; + + w = info->d_width*info->dst->BytesPerPixel; + h = info->d_height; + src = info->s_pixels; + dst = info->d_pixels; + srcskip = w+info->s_skip; + dstskip = w+info->d_skip; + if ( dst < src ) { + while ( h-- ) { + SDL_memmove(dst, src, w); + src += srcskip; + dst += dstskip; + } + } else { + src += ((h-1) * srcskip); + dst += ((h-1) * dstskip); + while ( h-- ) { + SDL_revcpy(dst, src, w); + src -= srcskip; + dst -= dstskip; + } + } +} + +/* Figure out which of many blit routines to set up on a surface */ +int SDL_CalculateBlit(SDL_Surface *surface) +{ + int blit_index; + + /* Clean everything out to start */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + surface->map->sw_blit = NULL; + + /* Figure out if an accelerated hardware blit is possible */ + surface->flags &= ~SDL_HWACCEL; + if ( surface->map->identity ) { + int hw_blit_ok; + + if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + /* We only support accelerated blitting to hardware */ + if ( surface->map->dst->flags & SDL_HWSURFACE ) { + hw_blit_ok = current_video->info.blit_hw; + } else { + hw_blit_ok = 0; + } + if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { + hw_blit_ok = current_video->info.blit_hw_CC; + } + if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { + hw_blit_ok = current_video->info.blit_hw_A; + } + } else { + /* We only support accelerated blitting to hardware */ + if ( surface->map->dst->flags & SDL_HWSURFACE ) { + hw_blit_ok = current_video->info.blit_sw; + } else { + hw_blit_ok = 0; + } + if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { + hw_blit_ok = current_video->info.blit_sw_CC; + } + if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { + hw_blit_ok = current_video->info.blit_sw_A; + } + } + if ( hw_blit_ok ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->CheckHWBlit(this, surface, surface->map->dst); + } + } + + /* if an alpha pixel format is specified, we can accelerate alpha blits */ + if (((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE )&&(current_video->displayformatalphapixel)) + { + if ( (surface->flags & SDL_SRCALPHA) ) + if ( current_video->info.blit_hw_A ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->CheckHWBlit(this, surface, surface->map->dst); + } + } + + /* Get the blit function index, based on surface mode */ + /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ + blit_index = 0; + blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; + if ( surface->flags & SDL_SRCALPHA + && (surface->format->alpha != SDL_ALPHA_OPAQUE + || surface->format->Amask) ) { + blit_index |= 2; + } + + /* Check for special "identity" case -- copy blit */ + if ( surface->map->identity && blit_index == 0 ) { + surface->map->sw_data->blit = SDL_BlitCopy; + + /* Handle overlapping blits on the same surface */ + if ( surface == surface->map->dst ) { + surface->map->sw_data->blit = SDL_BlitCopyOverlap; + } + } else { + if ( surface->format->BitsPerPixel < 8 ) { + surface->map->sw_data->blit = + SDL_CalculateBlit0(surface, blit_index); + } else { + switch ( surface->format->BytesPerPixel ) { + case 1: + surface->map->sw_data->blit = + SDL_CalculateBlit1(surface, blit_index); + break; + case 2: + case 3: + case 4: + surface->map->sw_data->blit = + SDL_CalculateBlitN(surface, blit_index); + break; + default: + surface->map->sw_data->blit = NULL; + break; + } + } + } + /* Make sure we have a blit function */ + if ( surface->map->sw_data->blit == NULL ) { + SDL_InvalidateMap(surface->map); + SDL_SetError("Blit combination not supported"); + return(-1); + } + + /* Choose software blitting function */ + if(surface->flags & SDL_RLEACCELOK + && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { + + if(surface->map->identity + && (blit_index == 1 + || (blit_index == 3 && !surface->format->Amask))) { + if ( SDL_RLESurface(surface) == 0 ) + surface->map->sw_blit = SDL_RLEBlit; + } else if(blit_index == 2 && surface->format->Amask) { + if ( SDL_RLESurface(surface) == 0 ) + surface->map->sw_blit = SDL_RLEAlphaBlit; + } + } + + if ( surface->map->sw_blit == NULL ) { + surface->map->sw_blit = SDL_SoftBlit; + } + return(0); +} + diff --git a/apps/plugins/sdl/src/video/SDL_blit.h b/apps/plugins/sdl/src/video/SDL_blit.h new file mode 100644 index 0000000000..d64c1e5cce --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit.h @@ -0,0 +1,528 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_blit_h +#define _SDL_blit_h + +#include "SDL_endian.h" + +/* The structure passed to the low level blit functions */ +typedef struct { + Uint8 *s_pixels; + int s_width; + int s_height; + int s_skip; + Uint8 *d_pixels; + int d_width; + int d_height; + int d_skip; + void *aux_data; + SDL_PixelFormat *src; + Uint8 *table; + SDL_PixelFormat *dst; +} SDL_BlitInfo; + +/* The type definition for the low level blit functions */ +typedef void (*SDL_loblit)(SDL_BlitInfo *info); + +/* This is the private info structure for software accelerated blits */ +struct private_swaccel { + SDL_loblit blit; + void *aux_data; +}; + +/* Blit mapping definition */ +typedef struct SDL_BlitMap { + SDL_Surface *dst; + int identity; + Uint8 *table; + SDL_blit hw_blit; + SDL_blit sw_blit; + struct private_hwaccel *hw_data; + struct private_swaccel *sw_data; + + /* the version count matches the destination; mismatch indicates + an invalid mapping */ + unsigned int format_version; +} SDL_BlitMap; + + +/* Functions found in SDL_blit.c */ +extern int SDL_CalculateBlit(SDL_Surface *surface); + +/* Functions found in SDL_blit_{0,1,N,A}.c */ +extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex); + +/* + * Useful macros for blitting routines + */ + +#define FORMAT_EQUAL(A, B) \ + ((A)->BitsPerPixel == (B)->BitsPerPixel \ + && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask)) + +/* Load pixel of the specified format from a buffer and get its R-G-B values */ +/* FIXME: rescale values to 0..255 here? */ +#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \ +{ \ + r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<Rloss); \ + g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<Gloss); \ + b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<Bloss); \ +} +#define RGB_FROM_RGB565(Pixel, r, g, b) \ +{ \ + r = (((Pixel&0xF800)>>11)<<3); \ + g = (((Pixel&0x07E0)>>5)<<2); \ + b = ((Pixel&0x001F)<<3); \ +} +#define RGB_FROM_RGB555(Pixel, r, g, b) \ +{ \ + r = (((Pixel&0x7C00)>>10)<<3); \ + g = (((Pixel&0x03E0)>>5)<<3); \ + b = ((Pixel&0x001F)<<3); \ +} +#define RGB_FROM_RGB888(Pixel, r, g, b) \ +{ \ + r = ((Pixel&0xFF0000)>>16); \ + g = ((Pixel&0xFF00)>>8); \ + b = (Pixel&0xFF); \ +} +#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \ +do { \ + switch (bpp) { \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: { \ + Uint8 *B = (Uint8 *)(buf); \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ + } else { \ + Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + Pixel = 0; /* appease gcc */ \ + break; \ + } \ +} while(0) + +#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \ +do { \ + switch (bpp) { \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: { \ + Uint8 *B = (Uint8 *)buf; \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ + } else { \ + Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + Pixel = 0; /* prevent gcc from complaining */ \ + break; \ + } \ + RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ +} while(0) + +/* Assemble R-G-B values into a specified pixel format and store them */ +#ifdef __NDS__ /* FIXME */ +#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ +{ \ + Pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift) | (1<<15); \ +} +#else +#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ +{ \ + Pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift); \ +} +#endif /* __NDS__ FIXME */ +#define RGB565_FROM_RGB(Pixel, r, g, b) \ +{ \ + Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \ +} +#define RGB555_FROM_RGB(Pixel, r, g, b) \ +{ \ + Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \ +} +#define RGB888_FROM_RGB(Pixel, r, g, b) \ +{ \ + Pixel = (r<<16)|(g<<8)|b; \ +} +#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 Pixel; \ + \ + PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ + *((Uint16 *)(buf)) = Pixel; \ + } \ + break; \ + \ + case 3: { \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 Pixel; \ + \ + PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ + *((Uint32 *)(buf)) = Pixel; \ + } \ + break; \ + } \ +} +#define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 *bufp; \ + Uint16 Pixel; \ + \ + bufp = (Uint16 *)buf; \ + PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ + *bufp = Pixel | (*bufp & Amask); \ + } \ + break; \ + \ + case 3: { \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 *bufp; \ + Uint32 Pixel; \ + \ + bufp = (Uint32 *)buf; \ + PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ + *bufp = Pixel | (*bufp & Amask); \ + } \ + break; \ + } \ +} + +/* FIXME: Should we rescale alpha into 0..255 here? */ +#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \ +{ \ + r = ((Pixel&fmt->Rmask)>>fmt->Rshift)<Rloss; \ + g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<Gloss; \ + b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<Bloss; \ + a = ((Pixel&fmt->Amask)>>fmt->Ashift)<Aloss; \ +} +#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \ +{ \ + r = (Pixel&fmt->Rmask)>>fmt->Rshift; \ + g = (Pixel&fmt->Gmask)>>fmt->Gshift; \ + b = (Pixel&fmt->Bmask)>>fmt->Bshift; \ + a = (Pixel&fmt->Amask)>>fmt->Ashift; \ +} +#define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \ +{ \ + r = (Pixel>>24); \ + g = ((Pixel>>16)&0xFF); \ + b = ((Pixel>>8)&0xFF); \ + a = (Pixel&0xFF); \ +} +#define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \ +{ \ + r = ((Pixel>>16)&0xFF); \ + g = ((Pixel>>8)&0xFF); \ + b = (Pixel&0xFF); \ + a = (Pixel>>24); \ +} +#define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \ +{ \ + r = (Pixel&0xFF); \ + g = ((Pixel>>8)&0xFF); \ + b = ((Pixel>>16)&0xFF); \ + a = (Pixel>>24); \ +} +#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \ +do { \ + switch (bpp) { \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: {/* FIXME: broken code (no alpha) */ \ + Uint8 *b = (Uint8 *)buf; \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + Pixel = b[0] + (b[1] << 8) + (b[2] << 16); \ + } else { \ + Pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + Pixel = 0; /* stop gcc complaints */ \ + break; \ + } \ + RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ + Pixel &= ~fmt->Amask; \ +} while(0) + +/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ +#ifdef __NDS__ /* FIXME */ +#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ +{ \ + Pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift)| \ + ((a>>fmt->Aloss)<Ashift) | (1<<15); \ +} +#else +#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ +{ \ + Pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift)| \ + ((a>>fmt->Aloss)<Ashift); \ +} +#endif /* __NDS__ FIXME */ +#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 Pixel; \ + \ + PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \ + *((Uint16 *)(buf)) = Pixel; \ + } \ + break; \ + \ + case 3: { /* FIXME: broken code (no alpha) */ \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 Pixel; \ + \ + PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \ + *((Uint32 *)(buf)) = Pixel; \ + } \ + break; \ + } \ +} + +/* Blend the RGB values of two Pixels based on a source alpha value */ +#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \ +do { \ + dR = (((sR-dR)*(A)+255)>>8)+dR; \ + dG = (((sG-dG)*(A)+255)>>8)+dG; \ + dB = (((sB-dB)*(A)+255)>>8)+dB; \ +} while(0) + + +/* This is a very useful loop for optimizing blitters */ +#if defined(_MSC_VER) && (_MSC_VER == 1300) +/* There's a bug in the Visual C++ 7 optimizer when compiling this code */ +#else +#define USE_DUFFS_LOOP +#endif +#ifdef USE_DUFFS_LOOP + +/* 8-times unrolled loop */ +#define DUFFS_LOOP8(pixel_copy_increment, width) \ +{ int n = (width+7)/8; \ + switch (width & 7) { \ + case 0: do { pixel_copy_increment; \ + case 7: pixel_copy_increment; \ + case 6: pixel_copy_increment; \ + case 5: pixel_copy_increment; \ + case 4: pixel_copy_increment; \ + case 3: pixel_copy_increment; \ + case 2: pixel_copy_increment; \ + case 1: pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ +} + +/* 4-times unrolled loop */ +#define DUFFS_LOOP4(pixel_copy_increment, width) \ +{ int n = (width+3)/4; \ + switch (width & 3) { \ + case 0: do { pixel_copy_increment; \ + case 3: pixel_copy_increment; \ + case 2: pixel_copy_increment; \ + case 1: pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ +} + +/* 2 - times unrolled loop */ +#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \ + double_pixel_copy_increment, width) \ +{ int n, w = width; \ + if( w & 1 ) { \ + pixel_copy_increment; \ + w--; \ + } \ + if ( w > 0 ) { \ + n = ( w + 2) / 4; \ + switch( w & 2 ) { \ + case 0: do { double_pixel_copy_increment; \ + case 2: double_pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ + } \ +} + +/* 2 - times unrolled loop 4 pixels */ +#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \ + double_pixel_copy_increment, \ + quatro_pixel_copy_increment, width) \ +{ int n, w = width; \ + if(w & 1) { \ + pixel_copy_increment; \ + w--; \ + } \ + if(w & 2) { \ + double_pixel_copy_increment; \ + w -= 2; \ + } \ + if ( w > 0 ) { \ + n = ( w + 7 ) / 8; \ + switch( w & 4 ) { \ + case 0: do { quatro_pixel_copy_increment; \ + case 4: quatro_pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ + } \ +} + +/* Use the 8-times version of the loop by default */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ + DUFFS_LOOP8(pixel_copy_increment, width) + +#else + +/* Don't use Duff's device to unroll loops */ +#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \ + double_pixel_copy_increment, width) \ +{ int n = width; \ + if( n & 1 ) { \ + pixel_copy_increment; \ + n--; \ + } \ + n=n>>1; \ + for(; n > 0; --n) { \ + double_pixel_copy_increment; \ + } \ +} + +/* Don't use Duff's device to unroll loops */ +#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \ + double_pixel_copy_increment, \ + quatro_pixel_copy_increment, width) \ +{ int n = width; \ + if(n & 1) { \ + pixel_copy_increment; \ + n--; \ + } \ + if(n & 2) { \ + double_pixel_copy_increment; \ + n -= 2; \ + } \ + n=n>>2; \ + for(; n > 0; --n) { \ + quatro_pixel_copy_increment; \ + } \ +} + +/* Don't use Duff's device to unroll loops */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ +{ int n; \ + for ( n=width; n > 0; --n ) { \ + pixel_copy_increment; \ + } \ +} +#define DUFFS_LOOP8(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) +#define DUFFS_LOOP4(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) + +#endif /* USE_DUFFS_LOOP */ + +/* Prevent Visual C++ 6.0 from printing out stupid warnings */ +#if defined(_MSC_VER) && (_MSC_VER >= 600) +#pragma warning(disable: 4550) +#endif + +#endif /* _SDL_blit_h */ diff --git a/apps/plugins/sdl/src/video/SDL_blit_0.c b/apps/plugins/sdl/src/video/SDL_blit_0.c new file mode 100644 index 0000000000..c1bc0eb61b --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit_0.c @@ -0,0 +1,471 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_blit.h" + +/* Functions to blit from bitmaps to other surfaces */ + +static void BlitBto1(SDL_BlitInfo *info) +{ + int c; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcskip += width-(width+7)/8; + + if ( map ) { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = bit; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } +} +static void BlitBto2(SDL_BlitInfo *info) +{ + int c; + int width, height; + Uint8 *src; + Uint16 *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + map = (Uint16 *)info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + byte <<= 1; + dst++; + } + src += srcskip; + dst += dstskip; + } +} +static void BlitBto3(SDL_BlitInfo *info) +{ + int c, o; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + o = bit * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + byte <<= 1; + dst += 3; + } + src += srcskip; + dst += dstskip; + } +} +static void BlitBto4(SDL_BlitInfo *info) +{ + int width, height; + Uint8 *src; + Uint32 *map, *dst; + int srcskip, dstskip; + int c; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + map = (Uint32 *)info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + byte <<= 1; + dst++; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBto1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + + if ( palmap ) { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dst = palmap[bit]; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dst = bit; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } +} + +static void BlitBto2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + dstskip /= 2; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dstp=((Uint16 *)palmap)[bit]; + } + byte <<= 1; + dstp++; + } + src += srcskip; + dstp += dstskip; + } +} + +static void BlitBto3Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + SDL_memcpy(dst, &palmap[bit*4], 3); + } + byte <<= 1; + dst += 3; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBto4Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + dstskip /= 4; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dstp=((Uint32 *)palmap)[bit]; + } + byte <<= 1; + dstp++; + } + src += srcskip; + dstp += dstskip; + } +} + +static void BlitBtoNAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + const SDL_Color *srcpal = info->src->palette->colors; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp; + int c; + const int A = info->src->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + Uint32 pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB; + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + byte <<= 1; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBtoNAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = srcfmt->palette->colors; + int dstbpp; + int c; + const int A = srcfmt->alpha; + Uint32 ckey = srcfmt->colorkey; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + int sR, sG, sB; + int dR, dG, dB; + Uint32 pixel; + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + byte <<= 1; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static SDL_loblit bitmap_blit[] = { + NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4 +}; + +static SDL_loblit colorkey_blit[] = { + NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key +}; + +SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index) +{ + int which; + + if ( surface->format->BitsPerPixel != 1 ) { + /* We don't support sub 8-bit packed pixel modes */ + return NULL; + } + if ( surface->map->dst->format->BitsPerPixel < 8 ) { + which = 0; + } else { + which = surface->map->dst->format->BytesPerPixel; + } + switch(blit_index) { + case 0: /* copy */ + return bitmap_blit[which]; + + case 1: /* colorkey */ + return colorkey_blit[which]; + + case 2: /* alpha */ + return which >= 2 ? BlitBtoNAlpha : NULL; + + case 4: /* alpha + colorkey */ + return which >= 2 ? BlitBtoNAlphaKey : NULL; + } + return NULL; +} + diff --git a/apps/plugins/sdl/src/video/SDL_blit_1.c b/apps/plugins/sdl/src/video/SDL_blit_1.c new file mode 100644 index 0000000000..7f95f5bf35 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit_1.c @@ -0,0 +1,523 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_blit.h" +#include "SDL_sysvideo.h" +#include "SDL_endian.h" + +/* Functions to blit from 8-bit surfaces to other surfaces */ + +static void Blit1to1(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + { + *dst = map[*src]; + } + dst++; + src++; + , width); +#else + for ( c=width; c; --c ) { + *dst = map[*src]; + dst++; + src++; + } +#endif + src += srcskip; + dst += dstskip; + } +} +/* This is now endian dependent */ +#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) +#define HI 1 +#define LO 0 +#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ +#define HI 0 +#define LO 1 +#endif +static void Blit1to2(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src, *dst; + Uint16 *map; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = (Uint16 *)info->table; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + { + *(Uint16 *)dst = map[*src++]; + dst += 2; + }, + width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + *(Uint16 *)dst = map[*src++]; + dst += 2; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *(Uint16 *)dst = map[*src++]; + dst += 2; + case 2: + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + break; + case 1: + *(Uint16 *)dst = map[*src++]; + dst += 2; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *(Uint16 *)dst = map[*src++]; + dst += 2; + case 2: + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + break; + case 1: + *(Uint16 *)dst = map[*src++]; + dst += 2; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} +static void Blit1to3(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int o; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + { + o = *src * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + src++; + dst += 3; + , width); +#else + for ( c=width; c; --c ) { + o = *src * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + src++; + dst += 3; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } +} +static void Blit1to4(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + Uint32 *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + map = (Uint32 *)info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + *dst++ = map[*src++]; + , width); +#else + for ( c=width/4; c; --c ) { + *dst++ = map[*src++]; + *dst++ = map[*src++]; + *dst++ = map[*src++]; + *dst++ = map[*src++]; + } + switch ( width & 3 ) { + case 3: + *dst++ = map[*src++]; + case 2: + *dst++ = map[*src++]; + case 1: + *dst++ = map[*src++]; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } +} + +static void Blit1to1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + Uint32 ckey = info->src->colorkey; + + if ( palmap ) { + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dst = palmap[*src]; + } + dst++; + src++; + }, + width); + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dst = *src; + } + dst++; + src++; + }, + width); + src += srcskip; + dst += dstskip; + } + } +} + +static void Blit1to2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip; + Uint16 *palmap = (Uint16 *)info->table; + Uint32 ckey = info->src->colorkey; + + /* Set up some basic variables */ + dstskip /= 2; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dstp=palmap[*src]; + } + src++; + dstp++; + }, + width); + src += srcskip; + dstp += dstskip; + } +} + +static void Blit1to3Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + Uint32 ckey = info->src->colorkey; + int o; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + o = *src * 4; + dst[0] = palmap[o++]; + dst[1] = palmap[o++]; + dst[2] = palmap[o++]; + } + src++; + dst += 3; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void Blit1to4Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip; + Uint32 *palmap = (Uint32 *)info->table; + Uint32 ckey = info->src->colorkey; + + /* Set up some basic variables */ + dstskip /= 4; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dstp = palmap[*src]; + } + src++; + dstp++; + }, + width); + src += srcskip; + dstp += dstskip; + } +} + +static void Blit1toNAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = info->src->palette->colors; + int dstbpp; + const int A = info->src->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + + while ( height-- ) { + int sR, sG, sB; + int dR, dG, dB; + DUFFS_LOOP4( + { + Uint32 pixel; + sR = srcpal[*src].r; + sG = srcpal[*src].g; + sB = srcpal[*src].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + src++; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void Blit1toNAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = info->src->palette->colors; + Uint32 ckey = srcfmt->colorkey; + int dstbpp; + const int A = srcfmt->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + + while ( height-- ) { + int sR, sG, sB; + int dR, dG, dB; + DUFFS_LOOP( + { + if ( *src != ckey ) { + Uint32 pixel; + sR = srcpal[*src].r; + sG = srcpal[*src].g; + sB = srcpal[*src].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + src++; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static SDL_loblit one_blit[] = { + NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 +}; + +static SDL_loblit one_blitkey[] = { + NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key +}; + +SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index) +{ + int which; + SDL_PixelFormat *dstfmt; + + dstfmt = surface->map->dst->format; + if ( dstfmt->BitsPerPixel < 8 ) { + which = 0; + } else { + which = dstfmt->BytesPerPixel; + } + switch(blit_index) { + case 0: /* copy */ + return one_blit[which]; + + case 1: /* colorkey */ + return one_blitkey[which]; + + case 2: /* alpha */ + /* Supporting 8bpp->8bpp alpha is doable but requires lots of + tables which consume space and takes time to precompute, + so is better left to the user */ + return which >= 2 ? Blit1toNAlpha : NULL; + + case 3: /* alpha + colorkey */ + return which >= 2 ? Blit1toNAlphaKey : NULL; + + } + return NULL; +} diff --git a/apps/plugins/sdl/src/video/SDL_blit_A.c b/apps/plugins/sdl/src/video/SDL_blit_A.c new file mode 100644 index 0000000000..219cdccf5b --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit_A.c @@ -0,0 +1,2873 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_blit.h" + +/* + In Visual C, VC6 has mmintrin.h in the "Processor Pack" add-on. + Checking if _mm_free is #defined in malloc.h is is the only way to + determine if the Processor Pack is installed, as far as I can tell. +*/ + +#if SDL_ASSEMBLY_ROUTINES +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + /* forced MMX to 0...it breaks on most compilers now. --ryan. */ +# define MMX_ASMBLIT 0 +# define GCC_ASMBLIT 0 +# elif defined(_MSC_VER) && defined(_M_IX86) +# if (_MSC_VER <= 1200) +# include +# if defined(_mm_free) +# define HAVE_MMINTRIN_H 1 +# endif +# else /* Visual Studio > VC6 always has mmintrin.h */ +# define HAVE_MMINTRIN_H 1 +# endif +# if HAVE_MMINTRIN_H +# define MMX_ASMBLIT 1 +# define MSVC_ASMBLIT 1 +# endif +# endif +#endif /* SDL_ASSEMBLY_ROUTINES */ + +/* Function to check the CPU flags */ +#include "SDL_cpuinfo.h" +#if GCC_ASMBLIT +#include "mmx.h" +#elif MSVC_ASMBLIT +#include +#include +#endif + +/* Functions to perform alpha blended blitting */ + +/* N->1 blending with per-surface alpha */ +static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + + const unsigned A = srcfmt->alpha; + + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2))| + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0))]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* N->1 blending with pixel alpha */ +static void BlitNto1PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + + /* FIXME: fix alpha bit field expansion here too? */ + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned sA; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2))| + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* colorkeyed N->1 blending with per-surface alpha */ +static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 ckey = srcfmt->colorkey; + + const int A = srcfmt->alpha; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + if ( Pixel != ckey ) { + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)) ]; + } + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +#if GCC_ASMBLIT +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + Uint32 dalpha = info->dst->Amask; + Uint64 load; + + load = 0x00fefefe00fefefeULL;/* alpha128 mask */ + movq_m2r(load, mm4); /* alpha128 mask -> mm4 */ + load = 0x0001010100010101ULL;/* !alpha128 mask */ + movq_m2r(load, mm3); /* !alpha128 mask -> mm3 */ + movd_m2r(dalpha, mm7); /* dst alpha mask */ + punpckldq_r2r(mm7, mm7); /* dst alpha mask | dst alpha mask -> mm7 */ + while(height--) { + DUFFS_LOOP_DOUBLE2( + { + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | dalpha; + },{ + movq_m2r((*dstp), mm2);/* 2 x dst -> mm2(ARGBARGB) */ + movq_r2r(mm2, mm6); /* 2 x dst -> mm6(ARGBARGB) */ + + movq_m2r((*srcp), mm1);/* 2 x src -> mm1(ARGBARGB) */ + movq_r2r(mm1, mm5); /* 2 x src -> mm5(ARGBARGB) */ + + pand_r2r(mm4, mm6); /* dst & mask -> mm6 */ + pand_r2r(mm4, mm5); /* src & mask -> mm5 */ + paddd_r2r(mm6, mm5); /* mm6 + mm5 -> mm5 */ + pand_r2r(mm1, mm2); /* src & dst -> mm2 */ + psrld_i2r(1, mm5); /* mm5 >> 1 -> mm5 */ + pand_r2r(mm3, mm2); /* mm2 & !mask -> mm2 */ + paddd_r2r(mm5, mm2); /* mm5 + mm2 -> mm2 */ + + por_r2r(mm7, mm2); /* mm7(full alpha) | mm2 -> mm2 */ + movq_r2m(mm2, (*dstp));/* mm2 -> 2 x dst pixels */ + dstp += 2; + srcp += 2; + }, width); + srcp += srcskip; + dstp += dstskip; + } + emms(); +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info) +{ + SDL_PixelFormat* df = info->dst; + unsigned alpha = info->src->alpha; + + if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) { + /* only call a128 version when R,G,B occupy lower bits */ + BlitRGBtoRGBSurfaceAlpha128MMX(info); + } else { + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + pxor_r2r(mm5, mm5); /* 0 -> mm5 */ + /* form the alpha mult */ + movd_m2r(alpha, mm4); /* 0000000A -> mm4 */ + punpcklwd_r2r(mm4, mm4); /* 00000A0A -> mm4 */ + punpckldq_r2r(mm4, mm4); /* 0A0A0A0A -> mm4 */ + alpha = (0xff << df->Rshift) | (0xff << df->Gshift) | (0xff << df->Bshift); + movd_m2r(alpha, mm0); /* 00000FFF -> mm0 */ + punpcklbw_r2r(mm0, mm0); /* 00FFFFFF -> mm0 */ + pand_r2r(mm0, mm4); /* 0A0A0A0A -> mm4, minus 1 chan */ + /* at this point mm4 can be 000A0A0A or 0A0A0A00 or another combo */ + movd_m2r(df->Amask, mm7); /* dst alpha mask */ + punpckldq_r2r(mm7, mm7); /* dst alpha mask | dst alpha mask -> mm7 */ + + while(height--) { + DUFFS_LOOP_DOUBLE2({ + /* One Pixel Blend */ + movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/ + movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/ + punpcklbw_r2r(mm5, mm1); /* 0A0R0G0B -> mm1(src) */ + punpcklbw_r2r(mm5, mm2); /* 0A0R0G0B -> mm2(dst) */ + + psubw_r2r(mm2, mm1);/* src - dst -> mm1 */ + pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */ + psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1 */ + paddb_r2r(mm1, mm2); /* mm1 + mm2(dst) -> mm2 */ + + packuswb_r2r(mm5, mm2); /* ARGBARGB -> mm2 */ + por_r2r(mm7, mm2); /* mm7(full alpha) | mm2 -> mm2 */ + movd_r2m(mm2, *dstp);/* mm2 -> pixel */ + ++srcp; + ++dstp; + },{ + /* Two Pixels Blend */ + movq_m2r((*srcp), mm0);/* 2 x src -> mm0(ARGBARGB)*/ + movq_m2r((*dstp), mm2);/* 2 x dst -> mm2(ARGBARGB) */ + movq_r2r(mm0, mm1); /* 2 x src -> mm1(ARGBARGB) */ + movq_r2r(mm2, mm6); /* 2 x dst -> mm6(ARGBARGB) */ + + punpcklbw_r2r(mm5, mm0); /* low - 0A0R0G0B -> mm0(src1) */ + punpckhbw_r2r(mm5, mm1); /* high - 0A0R0G0B -> mm1(src2) */ + punpcklbw_r2r(mm5, mm2); /* low - 0A0R0G0B -> mm2(dst1) */ + punpckhbw_r2r(mm5, mm6); /* high - 0A0R0G0B -> mm6(dst2) */ + + psubw_r2r(mm2, mm0);/* src1 - dst1 -> mm0 */ + pmullw_r2r(mm4, mm0); /* mm0 * alpha -> mm0 */ + psrlw_i2r(8, mm0); /* mm0 >> 8 -> mm1 */ + paddb_r2r(mm0, mm2); /* mm0 + mm2(dst1) -> mm2 */ + + psubw_r2r(mm6, mm1);/* src2 - dst2 -> mm1 */ + pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */ + psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1 */ + paddb_r2r(mm1, mm6); /* mm1 + mm6(dst2) -> mm6 */ + + packuswb_r2r(mm6, mm2); /* ARGBARGB -> mm2 */ + por_r2r(mm7, mm2); /* mm7(dst alpha) | mm2 -> mm2 */ + + movq_r2m(mm2, *dstp);/* mm2 -> 2 x pixel */ + + srcp += 2; + dstp += 2; + }, width); + srcp += srcskip; + dstp += dstskip; + } + emms(); + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat* sf = info->src; + Uint32 amask = sf->Amask; + + pxor_r2r(mm6, mm6); /* 0 -> mm6 */ + /* form multiplication mask */ + movd_m2r(sf->Amask, mm7); /* 0000F000 -> mm7 */ + punpcklbw_r2r(mm7, mm7); /* FF000000 -> mm7 */ + pcmpeqb_r2r(mm0, mm0); /* FFFFFFFF -> mm0 */ + movq_r2r(mm0, mm3); /* FFFFFFFF -> mm3 (for later) */ + pxor_r2r(mm0, mm7); /* 00FFFFFF -> mm7 (mult mask) */ + /* form channel masks */ + movq_r2r(mm7, mm0); /* 00FFFFFF -> mm0 */ + packsswb_r2r(mm6, mm0); /* 00000FFF -> mm0 (channel mask) */ + packsswb_r2r(mm6, mm3); /* 0000FFFF -> mm3 */ + pxor_r2r(mm0, mm3); /* 0000F000 -> mm3 (~channel mask) */ + /* get alpha channel shift */ + __asm__ __volatile__ ( + "movd %0, %%mm5" + : : "rm" ((Uint32) sf->Ashift) ); /* Ashift -> mm5 */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 alpha = *srcp & amask; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == 0) { + /* do nothing */ + } else if(alpha == amask) { + /* opaque alpha -- copy RGB, keep dst alpha */ + /* using MMX here to free up regular registers for other things */ + movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/ + movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/ + pand_r2r(mm0, mm1); /* src & chanmask -> mm1 */ + pand_r2r(mm3, mm2); /* dst & ~chanmask -> mm2 */ + por_r2r(mm1, mm2); /* src | dst -> mm2 */ + movd_r2m(mm2, (*dstp)); /* mm2 -> dst */ + } else { + movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/ + punpcklbw_r2r(mm6, mm1); /* 0A0R0G0B -> mm1 */ + + movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/ + punpcklbw_r2r(mm6, mm2); /* 0A0R0G0B -> mm2 */ + + __asm__ __volatile__ ( + "movd %0, %%mm4" + : : "r" (alpha) ); /* 0000A000 -> mm4 */ + psrld_r2r(mm5, mm4); /* mm4 >> mm5 -> mm4 (0000000A) */ + punpcklwd_r2r(mm4, mm4); /* 00000A0A -> mm4 */ + punpcklwd_r2r(mm4, mm4); /* 0A0A0A0A -> mm4 */ + pand_r2r(mm7, mm4); /* 000A0A0A -> mm4, preserve dst alpha on add */ + + /* blend */ + psubw_r2r(mm2, mm1);/* src - dst -> mm1 */ + pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */ + psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1(000R0G0B) */ + paddb_r2r(mm1, mm2); /* mm1 + mm2(dst) -> mm2 */ + + packuswb_r2r(mm6, mm2); /* 0000ARGB -> mm2 */ + movd_r2m(mm2, *dstp);/* mm2 -> dst */ + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + emms(); +} +/* End GCC_ASMBLIT */ + +#elif MSVC_ASMBLIT +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + Uint32 dalpha = info->dst->Amask; + + __m64 src1, src2, dst1, dst2, lmask, hmask, dsta; + + hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */ + lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + + while (height--) { + int n = width; + if ( n & 1 ) { + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | dalpha; + n--; + } + + for (n >>= 1; n > 0; --n) { + dst1 = *(__m64*)dstp; /* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + + src1 = *(__m64*)srcp; /* 2 x src -> src1(ARGBARGB) */ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + + dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */ + src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */ + src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */ + src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */ + + dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */ + dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */ + dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */ + + *(__m64*)dstp = dst1; /* dst1 -> 2 x dst pixels */ + dstp += 2; + srcp += 2; + } + + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info) +{ + SDL_PixelFormat* df = info->dst; + Uint32 chanmask = df->Rmask | df->Gmask | df->Bmask; + unsigned alpha = info->src->alpha; + + if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) { + /* only call a128 version when R,G,B occupy lower bits */ + BlitRGBtoRGBSurfaceAlpha128MMX(info); + } else { + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + Uint32 dalpha = df->Amask; + Uint32 amult; + + __m64 src1, src2, dst1, dst2, mm_alpha, mm_zero, dsta; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + /* form the alpha mult */ + amult = alpha | (alpha << 8); + amult = amult | (amult << 16); + chanmask = (0xff << df->Rshift) | (0xff << df->Gshift) | (0xff << df->Bshift); + mm_alpha = _mm_set_pi32(0, amult & chanmask); /* 0000AAAA -> mm_alpha, minus 1 chan */ + mm_alpha = _mm_unpacklo_pi8(mm_alpha, mm_zero); /* 0A0A0A0A -> mm_alpha, minus 1 chan */ + /* at this point mm_alpha can be 000A0A0A or 0A0A0A00 or another combo */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + + while (height--) { + int n = width; + if (n & 1) { + /* One Pixel Blend */ + src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB)*/ + src2 = _mm_unpacklo_pi8(src2, mm_zero); /* 0A0R0G0B -> src2 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */ + + dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + + ++srcp; + ++dstp; + + n--; + } + + for (n >>= 1; n > 0; --n) { + /* Two Pixels Blend */ + src1 = *(__m64*)srcp; /* 2 x src -> src1(ARGBARGB)*/ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* low - 0A0R0G0B -> src1 */ + src2 = _mm_unpackhi_pi8(src2, mm_zero); /* high - 0A0R0G0B -> src2 */ + + dst1 = *(__m64*)dstp;/* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* low - 0A0R0G0B -> dst1 */ + dst2 = _mm_unpackhi_pi8(dst2, mm_zero); /* high - 0A0R0G0B -> dst2 */ + + src1 = _mm_sub_pi16(src1, dst1);/* src1 - dst1 -> src1 */ + src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */ + src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */ + dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */ + + src2 = _mm_sub_pi16(src2, dst2);/* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */ + + dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + + *(__m64*)dstp = dst1; /* dst1 -> 2 x pixel */ + + srcp += 2; + dstp += 2; + } + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat* sf = info->src; + Uint32 chanmask = sf->Rmask | sf->Gmask | sf->Bmask; + Uint32 amask = sf->Amask; + Uint32 ashift = sf->Ashift; + Uint64 multmask; + + __m64 src1, dst1, mm_alpha, mm_zero, dmask; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + multmask = ~(0xFFFFi64 << (ashift * 2)); + dmask = *(__m64*) &multmask; /* dst alpha mask -> dmask */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 alpha = *srcp & amask; + if (alpha == 0) { + /* do nothing */ + } else if (alpha == amask) { + /* opaque alpha -- copy RGB, keep dst alpha */ + *dstp = (*srcp & chanmask) | (*dstp & ~chanmask); + } else { + src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB)*/ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */ + mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + mm_alpha = _mm_and_si64(mm_alpha, dmask); /* 000A0A0A -> mm_alpha, preserve dst alpha on add */ + + /* blend */ + src1 = _mm_sub_pi16(src1, dst1);/* src1 - dst1 -> src1 */ + src1 = _mm_mullo_pi16(src1, mm_alpha); /* (src1 - dst1) * alpha -> src1 */ + src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1(000R0G0B) */ + dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1 -> dst1(0A0R0G0B) */ + dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ + + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} +/* End MSVC_ASMBLIT */ + +#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */ + +#if SDL_ALTIVEC_BLITTERS +#if __MWERKS__ +#pragma altivec_model on +#endif +#if HAVE_ALTIVEC_H +#include +#endif +#include + +#if (defined(__MACOSX__) && (__GNUC__ < 4)) + #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p ) + #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ + (vector unsigned short) ( a,b,c,d,e,f,g,h ) +#else + #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p } + #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ + (vector unsigned short) { a,b,c,d,e,f,g,h } +#endif + +#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F) +#define VECPRINT(msg, v) do { \ + vector unsigned int tmpvec = (vector unsigned int)(v); \ + unsigned int *vp = (unsigned int *)&tmpvec; \ + printf("%s = %08X %08X %08X %08X\n", msg, vp[0], vp[1], vp[2], vp[3]); \ +} while (0) + +/* the permuation vector that takes the high bytes out of all the appropriate shorts + (vector unsigned char)( + 0x00, 0x10, 0x02, 0x12, + 0x04, 0x14, 0x06, 0x16, + 0x08, 0x18, 0x0A, 0x1A, + 0x0C, 0x1C, 0x0E, 0x1E ); +*/ +#define VEC_MERGE_PERMUTE() (vec_add(vec_lvsl(0, (int*)NULL), (vector unsigned char)vec_splat_u16(0x0F))) +#define VEC_U32_24() (vec_add(vec_splat_u32(12), vec_splat_u32(12))) +#define VEC_ALPHA_MASK() ((vector unsigned char)vec_sl((vector unsigned int)vec_splat_s8(-1), VEC_U32_24())) +#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \ + ? vec_lvsl(0, src) \ + : vec_add(vec_lvsl(8, src), vec_splat_u8(8))) + + +#define VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1_16, v8_16) do { \ + /* vtemp1 contains source AAGGAAGGAAGGAAGG */ \ + vector unsigned short vtemp1 = vec_mule(vs, valpha); \ + /* vtemp2 contains source RRBBRRBBRRBBRRBB */ \ + vector unsigned short vtemp2 = vec_mulo(vs, valpha); \ + /* valpha2 is 255-alpha */ \ + vector unsigned char valpha2 = vec_nor(valpha, valpha); \ + /* vtemp3 contains dest AAGGAAGGAAGGAAGG */ \ + vector unsigned short vtemp3 = vec_mule(vd, valpha2); \ + /* vtemp4 contains dest RRBBRRBBRRBBRRBB */ \ + vector unsigned short vtemp4 = vec_mulo(vd, valpha2); \ + /* add source and dest */ \ + vtemp1 = vec_add(vtemp1, vtemp3); \ + vtemp2 = vec_add(vtemp2, vtemp4); \ + /* vtemp1 = (vtemp1 + 1) + ((vtemp1 + 1) >> 8) */ \ + vtemp1 = vec_add(vtemp1, v1_16); \ + vtemp3 = vec_sr(vtemp1, v8_16); \ + vtemp1 = vec_add(vtemp1, vtemp3); \ + /* vtemp2 = (vtemp2 + 1) + ((vtemp2 + 1) >> 8) */ \ + vtemp2 = vec_add(vtemp2, v1_16); \ + vtemp4 = vec_sr(vtemp2, v8_16); \ + vtemp2 = vec_add(vtemp2, vtemp4); \ + /* (>>8) and get ARGBARGBARGBARGB */ \ + vd = (vector unsigned char)vec_perm(vtemp1, vtemp2, mergePermute); \ +} while (0) + +/* Calculate the permute vector used for 32->32 swizzling */ +static vector unsigned char calc_swizzle32(const SDL_PixelFormat *srcfmt, + const SDL_PixelFormat *dstfmt) +{ + /* + * We have to assume that the bits that aren't used by other + * colors is alpha, and it's one complete byte, since some formats + * leave alpha with a zero mask, but we should still swizzle the bits. + */ + /* ARGB */ + const static struct SDL_PixelFormat default_pixel_format = { + NULL, 0, 0, + 0, 0, 0, 0, + 16, 8, 0, 24, + 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, + 0, 0}; + if (!srcfmt) { + srcfmt = &default_pixel_format; + } + if (!dstfmt) { + dstfmt = &default_pixel_format; + } + const vector unsigned char plus = VECUINT8_LITERAL + ( 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x04, 0x04, + 0x08, 0x08, 0x08, 0x08, + 0x0C, 0x0C, 0x0C, 0x0C ); + vector unsigned char vswiz; + vector unsigned int srcvec; +#define RESHIFT(X) (3 - ((X) >> 3)) + Uint32 rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift); + Uint32 gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift); + Uint32 bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift); + Uint32 amask; + /* Use zero for alpha if either surface doesn't have alpha */ + if (dstfmt->Amask) { + amask = ((srcfmt->Amask) ? RESHIFT(srcfmt->Ashift) : 0x10) << (dstfmt->Ashift); + } else { + amask = 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^ 0xFFFFFFFF); + } +#undef RESHIFT + ((unsigned int *)(char*)&srcvec)[0] = (rmask | gmask | bmask | amask); + vswiz = vec_add(plus, (vector unsigned char)vec_splat(srcvec, 0)); + return(vswiz); +} + +static void Blit32to565PixelAlphaAltivec(SDL_BlitInfo *info) +{ + int height = info->d_height; + Uint8 *src = (Uint8 *)info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = (Uint8 *)info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + + vector unsigned char v0 = vec_splat_u8(0); + vector unsigned short v8_16 = vec_splat_u16(8); + vector unsigned short v1_16 = vec_splat_u16(1); + vector unsigned short v2_16 = vec_splat_u16(2); + vector unsigned short v3_16 = vec_splat_u16(3); + vector unsigned int v8_32 = vec_splat_u32(8); + vector unsigned int v16_32 = vec_add(v8_32, v8_32); + vector unsigned short v3f = VECUINT16_LITERAL( + 0x003f, 0x003f, 0x003f, 0x003f, + 0x003f, 0x003f, 0x003f, 0x003f); + vector unsigned short vfc = VECUINT16_LITERAL( + 0x00fc, 0x00fc, 0x00fc, 0x00fc, + 0x00fc, 0x00fc, 0x00fc, 0x00fc); + + /* + 0x10 - 0x1f is the alpha + 0x00 - 0x0e evens are the red + 0x01 - 0x0f odds are zero + */ + vector unsigned char vredalpha1 = VECUINT8_LITERAL( + 0x10, 0x00, 0x01, 0x01, + 0x10, 0x02, 0x01, 0x01, + 0x10, 0x04, 0x01, 0x01, + 0x10, 0x06, 0x01, 0x01 + ); + vector unsigned char vredalpha2 = (vector unsigned char)( + vec_add((vector unsigned int)vredalpha1, vec_sl(v8_32, v16_32)) + ); + /* + 0x00 - 0x0f is ARxx ARxx ARxx ARxx + 0x11 - 0x0f odds are blue + */ + vector unsigned char vblue1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x02, 0x11, + 0x04, 0x05, 0x06, 0x13, + 0x08, 0x09, 0x0a, 0x15, + 0x0c, 0x0d, 0x0e, 0x17 + ); + vector unsigned char vblue2 = (vector unsigned char)( + vec_add((vector unsigned int)vblue1, v8_32) + ); + /* + 0x00 - 0x0f is ARxB ARxB ARxB ARxB + 0x10 - 0x0e evens are green + */ + vector unsigned char vgreen1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x10, 0x03, + 0x04, 0x05, 0x12, 0x07, + 0x08, 0x09, 0x14, 0x0b, + 0x0c, 0x0d, 0x16, 0x0f + ); + vector unsigned char vgreen2 = (vector unsigned char)( + vec_add((vector unsigned int)vgreen1, vec_sl(v8_32, v8_32)) + ); + vector unsigned char vgmerge = VECUINT8_LITERAL( + 0x00, 0x02, 0x00, 0x06, + 0x00, 0x0a, 0x00, 0x0e, + 0x00, 0x12, 0x00, 0x16, + 0x00, 0x1a, 0x00, 0x1e); + vector unsigned char mergePermute = VEC_MERGE_PERMUTE(); + vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL); + vector unsigned char valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC)); + + vector unsigned short vf800 = (vector unsigned short)vec_splat_u8(-7); + vf800 = vec_sl(vf800, vec_splat_u16(8)); + + while(height--) { + int extrawidth; + vector unsigned char valigner; + vector unsigned char vsrc; + vector unsigned char voverflow; + int width = info->d_width; + +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, dR, dG, dB, sA; \ + DISEMBLE_RGBA(src, 4, srcfmt, Pixel, sR, sG, sB, sA); \ + if(sA) { \ + unsigned short dstpixel = *((unsigned short *)dst); \ + dR = (dstpixel >> 8) & 0xf8; \ + dG = (dstpixel >> 3) & 0xfc; \ + dB = (dstpixel << 3) & 0xf8; \ + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \ + *((unsigned short *)dst) = ( \ + ((dR & 0xf8) << 8) | ((dG & 0xfc) << 3) | (dB >> 3) \ + ); \ + } \ + src += 4; \ + dst += 2; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dst)) && (width), width); + extrawidth = (width % 8); + valigner = VEC_ALIGNER(src); + vsrc = (vector unsigned char)vec_ld(0, src); + width -= extrawidth; + while (width) { + vector unsigned char valpha; + vector unsigned char vsrc1, vsrc2; + vector unsigned char vdst1, vdst2; + vector unsigned short vR, vG, vB; + vector unsigned short vpixel, vrpixel, vgpixel, vbpixel; + + /* Load 8 pixels from src as ARGB */ + voverflow = (vector unsigned char)vec_ld(15, src); + vsrc = vec_perm(vsrc, voverflow, valigner); + vsrc1 = vec_perm(vsrc, vsrc, vpermute); + src += 16; + vsrc = (vector unsigned char)vec_ld(15, src); + voverflow = vec_perm(voverflow, vsrc, valigner); + vsrc2 = vec_perm(voverflow, voverflow, vpermute); + src += 16; + + /* Load 8 pixels from dst as XRGB */ + voverflow = vec_ld(0, dst); + vR = vec_and((vector unsigned short)voverflow, vf800); + vB = vec_sl((vector unsigned short)voverflow, v3_16); + vG = vec_sl(vB, v2_16); + vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, (vector unsigned char)vR, vredalpha1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); + vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, (vector unsigned char)vR, vredalpha2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2); + + /* Alpha blend 8 pixels as ARGB */ + valpha = vec_perm(vsrc1, v0, valphaPermute); + VEC_MULTIPLY_ALPHA(vsrc1, vdst1, valpha, mergePermute, v1_16, v8_16); + valpha = vec_perm(vsrc2, v0, valphaPermute); + VEC_MULTIPLY_ALPHA(vsrc2, vdst2, valpha, mergePermute, v1_16, v8_16); + + /* Convert 8 pixels to 565 */ + vpixel = (vector unsigned short)vec_packpx((vector unsigned int)vdst1, (vector unsigned int)vdst2); + vgpixel = (vector unsigned short)vec_perm(vdst1, vdst2, vgmerge); + vgpixel = vec_and(vgpixel, vfc); + vgpixel = vec_sl(vgpixel, v3_16); + vrpixel = vec_sl(vpixel, v1_16); + vrpixel = vec_and(vrpixel, vf800); + vbpixel = vec_and(vpixel, v3f); + vdst1 = vec_or((vector unsigned char)vrpixel, (vector unsigned char)vgpixel); + vdst1 = vec_or(vdst1, (vector unsigned char)vbpixel); + + /* Store 8 pixels */ + vec_st(vdst1, 0, dst); + + width -= 8; + dst += 16; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); +#undef ONE_PIXEL_BLEND + src += srcskip; + dst += dstskip; + } +} + +static void Blit32to32SurfaceAlphaKeyAltivec(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; + Uint32 ckey = info->src->colorkey; + vector unsigned char mergePermute; + vector unsigned char vsrcPermute; + vector unsigned char vdstPermute; + vector unsigned char vsdstPermute; + vector unsigned char valpha; + vector unsigned char valphamask; + vector unsigned char vbits; + vector unsigned char v0; + vector unsigned short v1; + vector unsigned short v8; + vector unsigned int vckey; + vector unsigned int vrgbmask; + + mergePermute = VEC_MERGE_PERMUTE(); + v0 = vec_splat_u8(0); + v1 = vec_splat_u16(1); + v8 = vec_splat_u16(8); + + /* set the alpha to 255 on the destination surf */ + valphamask = VEC_ALPHA_MASK(); + + vsrcPermute = calc_swizzle32(srcfmt, NULL); + vdstPermute = calc_swizzle32(NULL, dstfmt); + vsdstPermute = calc_swizzle32(dstfmt, NULL); + + /* set a vector full of alpha and 255-alpha */ + ((unsigned char *)&valpha)[0] = alpha; + valpha = vec_splat(valpha, 0); + vbits = (vector unsigned char)vec_splat_s8(-1); + + ckey &= rgbmask; + ((unsigned int *)(char*)&vckey)[0] = ckey; + vckey = vec_splat(vckey, 0); + ((unsigned int *)(char*)&vrgbmask)[0] = rgbmask; + vrgbmask = vec_splat(vrgbmask, 0); + + while(height--) { + int width = info->d_width; +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, dR, dG, dB; \ + RETRIEVE_RGB_PIXEL(((Uint8 *)srcp), 4, Pixel); \ + if(sA && Pixel != ckey) { \ + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \ + DISEMBLE_RGB(((Uint8 *)dstp), 4, dstfmt, Pixel, dR, dG, dB); \ + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \ + ASSEMBLE_RGBA(((Uint8 *)dstp), 4, dstfmt, dR, dG, dB, dA); \ + } \ + dstp++; \ + srcp++; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + if (width > 0) { + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); + width -= extrawidth; + while (width) { + vector unsigned char vsel; + vector unsigned char voverflow; + vector unsigned char vd; + vector unsigned char vd_orig; + + /* s = *srcp */ + voverflow = (vector unsigned char)vec_ld(15, srcp); + vs = vec_perm(vs, voverflow, valigner); + + /* vsel is set for items that match the key */ + vsel = (vector unsigned char)vec_and((vector unsigned int)vs, vrgbmask); + vsel = (vector unsigned char)vec_cmpeq((vector unsigned int)vsel, vckey); + + /* permute to source format */ + vs = vec_perm(vs, valpha, vsrcPermute); + + /* d = *dstp */ + vd = (vector unsigned char)vec_ld(0, dstp); + vd_orig = vd = vec_perm(vd, v0, vsdstPermute); + + VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8); + + /* set the alpha channel to full on */ + vd = vec_or(vd, valphamask); + + /* mask out color key */ + vd = vec_sel(vd, vd_orig, vsel); + + /* permute to dest format */ + vd = vec_perm(vd, vbits, vdstPermute); + + /* *dstp = res */ + vec_st((vector unsigned int)vd, 0, dstp); + + srcp += 4; + dstp += 4; + width -= 4; + vs = voverflow; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); + } +#undef ONE_PIXEL_BLEND + + srcp += srcskip; + dstp += dstskip; + } +} + + +static void Blit32to32PixelAlphaAltivec(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + vector unsigned char mergePermute; + vector unsigned char valphaPermute; + vector unsigned char vsrcPermute; + vector unsigned char vdstPermute; + vector unsigned char vsdstPermute; + vector unsigned char valphamask; + vector unsigned char vpixelmask; + vector unsigned char v0; + vector unsigned short v1; + vector unsigned short v8; + + v0 = vec_splat_u8(0); + v1 = vec_splat_u16(1); + v8 = vec_splat_u16(8); + mergePermute = VEC_MERGE_PERMUTE(); + valphamask = VEC_ALPHA_MASK(); + valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC)); + vpixelmask = vec_nor(valphamask, v0); + vsrcPermute = calc_swizzle32(srcfmt, NULL); + vdstPermute = calc_swizzle32(NULL, dstfmt); + vsdstPermute = calc_swizzle32(dstfmt, NULL); + + while ( height-- ) { + width = info->d_width; +#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, dR, dG, dB, sA, dA; \ + DISEMBLE_RGBA((Uint8 *)srcp, 4, srcfmt, Pixel, sR, sG, sB, sA); \ + if(sA) { \ + DISEMBLE_RGBA((Uint8 *)dstp, 4, dstfmt, Pixel, dR, dG, dB, dA); \ + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \ + ASSEMBLE_RGBA((Uint8 *)dstp, 4, dstfmt, dR, dG, dB, dA); \ + } \ + ++srcp; \ + ++dstp; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + if (width > 0) { + /* vsrcPermute */ + /* vdstPermute */ + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); + width -= extrawidth; + while (width) { + vector unsigned char voverflow; + vector unsigned char vd; + vector unsigned char valpha; + vector unsigned char vdstalpha; + /* s = *srcp */ + voverflow = (vector unsigned char)vec_ld(15, srcp); + vs = vec_perm(vs, voverflow, valigner); + vs = vec_perm(vs, v0, vsrcPermute); + + valpha = vec_perm(vs, v0, valphaPermute); + + /* d = *dstp */ + vd = (vector unsigned char)vec_ld(0, dstp); + vd = vec_perm(vd, v0, vsdstPermute); + vdstalpha = vec_and(vd, valphamask); + + VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8); + + /* set the alpha to the dest alpha */ + vd = vec_and(vd, vpixelmask); + vd = vec_or(vd, vdstalpha); + vd = vec_perm(vd, v0, vdstPermute); + + /* *dstp = res */ + vec_st((vector unsigned int)vd, 0, dstp); + + srcp += 4; + dstp += 4; + width -= 4; + vs = voverflow; + + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); + } + srcp += srcskip; + dstp += dstskip; +#undef ONE_PIXEL_BLEND + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlphaAltivec(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + vector unsigned char mergePermute; + vector unsigned char valphaPermute; + vector unsigned char valphamask; + vector unsigned char vpixelmask; + vector unsigned char v0; + vector unsigned short v1; + vector unsigned short v8; + v0 = vec_splat_u8(0); + v1 = vec_splat_u16(1); + v8 = vec_splat_u16(8); + mergePermute = VEC_MERGE_PERMUTE(); + valphamask = VEC_ALPHA_MASK(); + valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC)); + + + vpixelmask = vec_nor(valphamask, v0); + while(height--) { + width = info->d_width; +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while ((condition)) { \ + Uint32 dalpha; \ + Uint32 d; \ + Uint32 s1; \ + Uint32 d1; \ + Uint32 s = *srcp; \ + Uint32 alpha = s >> 24; \ + if(alpha) { \ + if(alpha == SDL_ALPHA_OPAQUE) { \ + *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); \ + } else { \ + d = *dstp; \ + dalpha = d & 0xff000000; \ + s1 = s & 0xff00ff; \ + d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + *dstp = d1 | d | dalpha; \ + } \ + } \ + ++srcp; \ + ++dstp; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + if (width > 0) { + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); + width -= extrawidth; + while (width) { + vector unsigned char voverflow; + vector unsigned char vd; + vector unsigned char valpha; + vector unsigned char vdstalpha; + /* s = *srcp */ + voverflow = (vector unsigned char)vec_ld(15, srcp); + vs = vec_perm(vs, voverflow, valigner); + + valpha = vec_perm(vs, v0, valphaPermute); + + /* d = *dstp */ + vd = (vector unsigned char)vec_ld(0, dstp); + vdstalpha = vec_and(vd, valphamask); + + VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8); + + /* set the alpha to the dest alpha */ + vd = vec_and(vd, vpixelmask); + vd = vec_or(vd, vdstalpha); + + /* *dstp = res */ + vec_st((vector unsigned int)vd, 0, dstp); + + srcp += 4; + dstp += 4; + width -= 4; + vs = voverflow; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); + } + srcp += srcskip; + dstp += dstskip; + } +#undef ONE_PIXEL_BLEND +} + +static void Blit32to32SurfaceAlphaAltivec(SDL_BlitInfo *info) +{ + /* XXX : 6 */ + unsigned alpha = info->src->alpha; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + vector unsigned char mergePermute; + vector unsigned char vsrcPermute; + vector unsigned char vdstPermute; + vector unsigned char vsdstPermute; + vector unsigned char valpha; + vector unsigned char valphamask; + vector unsigned char vbits; + vector unsigned short v1; + vector unsigned short v8; + + mergePermute = VEC_MERGE_PERMUTE(); + v1 = vec_splat_u16(1); + v8 = vec_splat_u16(8); + + /* set the alpha to 255 on the destination surf */ + valphamask = VEC_ALPHA_MASK(); + + vsrcPermute = calc_swizzle32(srcfmt, NULL); + vdstPermute = calc_swizzle32(NULL, dstfmt); + vsdstPermute = calc_swizzle32(dstfmt, NULL); + + /* set a vector full of alpha and 255-alpha */ + ((unsigned char *)&valpha)[0] = alpha; + valpha = vec_splat(valpha, 0); + vbits = (vector unsigned char)vec_splat_s8(-1); + + while(height--) { + int width = info->d_width; +#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, dR, dG, dB; \ + DISEMBLE_RGB(((Uint8 *)srcp), 4, srcfmt, Pixel, sR, sG, sB); \ + DISEMBLE_RGB(((Uint8 *)dstp), 4, dstfmt, Pixel, dR, dG, dB); \ + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \ + ASSEMBLE_RGBA(((Uint8 *)dstp), 4, dstfmt, dR, dG, dB, dA); \ + ++srcp; \ + ++dstp; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + if (width > 0) { + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); + width -= extrawidth; + while (width) { + vector unsigned char voverflow; + vector unsigned char vd; + + /* s = *srcp */ + voverflow = (vector unsigned char)vec_ld(15, srcp); + vs = vec_perm(vs, voverflow, valigner); + vs = vec_perm(vs, valpha, vsrcPermute); + + /* d = *dstp */ + vd = (vector unsigned char)vec_ld(0, dstp); + vd = vec_perm(vd, vd, vsdstPermute); + + VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8); + + /* set the alpha channel to full on */ + vd = vec_or(vd, valphamask); + vd = vec_perm(vd, vbits, vdstPermute); + + /* *dstp = res */ + vec_st((vector unsigned int)vd, 0, dstp); + + srcp += 4; + dstp += 4; + width -= 4; + vs = voverflow; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); + } +#undef ONE_PIXEL_BLEND + + srcp += srcskip; + dstp += dstskip; + } + +} + + +/* fast RGB888->(A)RGB888 blending */ +static void BlitRGBtoRGBSurfaceAlphaAltivec(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + vector unsigned char mergePermute; + vector unsigned char valpha; + vector unsigned char valphamask; + vector unsigned short v1; + vector unsigned short v8; + + mergePermute = VEC_MERGE_PERMUTE(); + v1 = vec_splat_u16(1); + v8 = vec_splat_u16(8); + + /* set the alpha to 255 on the destination surf */ + valphamask = VEC_ALPHA_MASK(); + + /* set a vector full of alpha and 255-alpha */ + ((unsigned char *)&valpha)[0] = alpha; + valpha = vec_splat(valpha, 0); + + while(height--) { + int width = info->d_width; +#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \ + Uint32 s = *srcp; \ + Uint32 d = *dstp; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) \ + & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + *dstp = d1 | d | 0xff000000; \ + ++srcp; \ + ++dstp; \ + widthvar--; \ + } + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + if (width > 0) { + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); + width -= extrawidth; + while (width) { + vector unsigned char voverflow; + vector unsigned char vd; + + /* s = *srcp */ + voverflow = (vector unsigned char)vec_ld(15, srcp); + vs = vec_perm(vs, voverflow, valigner); + + /* d = *dstp */ + vd = (vector unsigned char)vec_ld(0, dstp); + + VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8); + + /* set the alpha channel to full on */ + vd = vec_or(vd, valphamask); + + /* *dstp = res */ + vec_st((vector unsigned int)vd, 0, dstp); + + srcp += 4; + dstp += 4; + width -= 4; + vs = voverflow; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); + } +#undef ONE_PIXEL_BLEND + + srcp += srcskip; + dstp += dstskip; + } +} +#if __MWERKS__ +#pragma altivec_model off +#endif +#endif /* SDL_ALTIVEC_BLITTERS */ + +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | 0xff000000; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + BlitRGBtoRGBSurfaceAlpha128(info); + } else { + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + Uint32 s; + Uint32 d; + Uint32 s1; + Uint32 d1; + + while(height--) { + DUFFS_LOOP_DOUBLE2({ + /* One Pixel Blend */ + s = *srcp; + d = *dstp; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) + & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | 0xff000000; + ++srcp; + ++dstp; + },{ + /* Two Pixels Blend */ + s = *srcp; + d = *dstp; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 += (s1 - d1) * alpha >> 8; + d1 &= 0xff00ff; + + s = ((s & 0xff00) >> 8) | + ((srcp[1] & 0xff00) << 8); + d = ((d & 0xff00) >> 8) | + ((dstp[1] & 0xff00) << 8); + d += (s - d) * alpha >> 8; + d &= 0x00ff00ff; + + *dstp++ = d1 | ((d << 8) & 0xff00) | 0xff000000; + ++srcp; + + s1 = *srcp; + d1 = *dstp; + s1 &= 0xff00ff; + d1 &= 0xff00ff; + d1 += (s1 - d1) * alpha >> 8; + d1 &= 0xff00ff; + + *dstp = d1 | ((d >> 8) & 0xff00) | 0xff000000; + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + while(height--) { + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) { + if(alpha == SDL_ALPHA_OPAQUE) { + *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); + } else { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + d = *dstp; + dalpha = d & 0xff000000; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | dalpha; + } + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +#if GCC_ASMBLIT +/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat* sf = info->src; + Uint32 amask = sf->Amask; + + __asm__ ( + /* make mm6 all zeros. */ + "pxor %%mm6, %%mm6\n" + + /* Make a mask to preserve the alpha. */ + "movd %0, %%mm7\n\t" /* 0000F000 -> mm7 */ + "punpcklbw %%mm7, %%mm7\n\t" /* FF000000 -> mm7 */ + "pcmpeqb %%mm4, %%mm4\n\t" /* FFFFFFFF -> mm4 */ + "movq %%mm4, %%mm3\n\t" /* FFFFFFFF -> mm3 (for later) */ + "pxor %%mm4, %%mm7\n\t" /* 00FFFFFF -> mm7 (mult mask) */ + + /* form channel masks */ + "movq %%mm7, %%mm4\n\t" /* 00FFFFFF -> mm4 */ + "packsswb %%mm6, %%mm4\n\t" /* 00000FFF -> mm4 (channel mask) */ + "packsswb %%mm6, %%mm3\n\t" /* 0000FFFF -> mm3 */ + "pxor %%mm4, %%mm3\n\t" /* 0000F000 -> mm3 (~channel mask) */ + + /* get alpha channel shift */ + "movd %1, %%mm5\n\t" /* Ashift -> mm5 */ + + : /* nothing */ : "rm" (amask), "rm" ((Uint32) sf->Ashift) ); + + while(height--) { + + DUFFS_LOOP4({ + Uint32 alpha; + + __asm__ ( + "prefetch 64(%0)\n" + "prefetch 64(%1)\n" + : : "r" (srcp), "r" (dstp) ); + + alpha = *srcp & amask; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == 0) { + /* do nothing */ + } + else if(alpha == amask) { + /* opaque alpha -- copy RGB, keep dst alpha */ + /* using MMX here to free up regular registers for other things */ + __asm__ ( + "movd (%0), %%mm0\n\t" /* src(ARGB) -> mm0 (0000ARGB)*/ + "movd (%1), %%mm1\n\t" /* dst(ARGB) -> mm1 (0000ARGB)*/ + "pand %%mm4, %%mm0\n\t" /* src & chanmask -> mm0 */ + "pand %%mm3, %%mm1\n\t" /* dst & ~chanmask -> mm2 */ + "por %%mm0, %%mm1\n\t" /* src | dst -> mm1 */ + "movd %%mm1, (%1) \n\t" /* mm1 -> dst */ + + : : "r" (srcp), "r" (dstp) ); + } + + else { + __asm__ ( + /* load in the source, and dst. */ + "movd (%0), %%mm0\n" /* mm0(s) = 0 0 0 0 | As Rs Gs Bs */ + "movd (%1), %%mm1\n" /* mm1(d) = 0 0 0 0 | Ad Rd Gd Bd */ + + /* Move the src alpha into mm2 */ + + /* if supporting pshufw */ + /*"pshufw $0x55, %%mm0, %%mm2\n" */ /* mm2 = 0 As 0 As | 0 As 0 As */ + /*"psrlw $8, %%mm2\n" */ + + /* else: */ + "movd %2, %%mm2\n" + "psrld %%mm5, %%mm2\n" /* mm2 = 0 0 0 0 | 0 0 0 As */ + "punpcklwd %%mm2, %%mm2\n" /* mm2 = 0 0 0 0 | 0 As 0 As */ + "punpckldq %%mm2, %%mm2\n" /* mm2 = 0 As 0 As | 0 As 0 As */ + "pand %%mm7, %%mm2\n" /* to preserve dest alpha */ + + /* move the colors into words. */ + "punpcklbw %%mm6, %%mm0\n" /* mm0 = 0 As 0 Rs | 0 Gs 0 Bs */ + "punpcklbw %%mm6, %%mm1\n" /* mm0 = 0 Ad 0 Rd | 0 Gd 0 Bd */ + + /* src - dst */ + "psubw %%mm1, %%mm0\n" /* mm0 = As-Ad Rs-Rd | Gs-Gd Bs-Bd */ + + /* A * (src-dst) */ + "pmullw %%mm2, %%mm0\n" /* mm0 = 0*As-d As*Rs-d | As*Gs-d As*Bs-d */ + "psrlw $8, %%mm0\n" /* mm0 = 0>>8 Rc>>8 | Gc>>8 Bc>>8 */ + "paddb %%mm1, %%mm0\n" /* mm0 = 0+Ad Rc+Rd | Gc+Gd Bc+Bd */ + + "packuswb %%mm0, %%mm0\n" /* mm0 = | Ac Rc Gc Bc */ + + "movd %%mm0, (%1)\n" /* result in mm0 */ + + : : "r" (srcp), "r" (dstp), "r" (alpha) ); + + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + + __asm__ ( + "emms\n" + : ); +} +/* End GCC_ASMBLIT*/ + +#elif MSVC_ASMBLIT +/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + SDL_PixelFormat* sf = info->src; + Uint32 chanmask = sf->Rmask | sf->Gmask | sf->Bmask; + Uint32 amask = sf->Amask; + Uint32 ashift = sf->Ashift; + Uint64 multmask; + + __m64 src1, dst1, mm_alpha, mm_zero, dmask; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + multmask = ~(0xFFFFi64 << (ashift * 2)); + dmask = *(__m64*) &multmask; /* dst alpha mask -> dmask */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 alpha; + + _m_prefetch(srcp + 16); + _m_prefetch(dstp + 16); + + alpha = *srcp & amask; + if (alpha == 0) { + /* do nothing */ + } else if (alpha == amask) { + /* copy RGB, keep dst alpha */ + *dstp = (*srcp & chanmask) | (*dstp & ~chanmask); + } else { + src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB)*/ + src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */ + + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/ + dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ + + mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */ + mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + mm_alpha = _mm_and_si64(mm_alpha, dmask); /* 000A0A0A -> mm_alpha, preserve dst alpha on add */ + + /* blend */ + src1 = _mm_sub_pi16(src1, dst1);/* src - dst -> src1 */ + src1 = _mm_mullo_pi16(src1, mm_alpha); /* (src - dst) * alpha -> src1 */ + src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1(000R0G0B) */ + dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst) -> dst1(0A0R0G0B) */ + dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ + + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); +} +/* End MSVC_ASMBLIT */ + +#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */ + +/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ + +/* blend a single 16 bit pixel at 50% */ +#define BLEND16_50(d, s, mask) \ + ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) + +/* blend two 16 bit pixels at 50% */ +#define BLEND2x16_50(d, s, mask) \ + (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16)))) + +static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) +{ + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + if(((uintptr_t)srcp ^ (uintptr_t)dstp) & 2) { + /* + * Source and destination not aligned, pipeline it. + * This is mostly a win for big blits but no loss for + * small ones + */ + Uint32 prev_sw; + int w = width; + + /* handle odd destination */ + if((uintptr_t)dstp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + dstp++; + srcp++; + w--; + } + srcp++; /* srcp is now 32-bit aligned */ + + /* bootstrap pipeline with first halfword */ + prev_sw = ((Uint32 *)srcp)[-1]; + + while(w > 1) { + Uint32 sw, dw, s; + sw = *(Uint32 *)srcp; + dw = *(Uint32 *)dstp; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + s = (prev_sw << 16) + (sw >> 16); +#else + s = (prev_sw >> 16) + (sw << 16); +#endif + prev_sw = sw; + *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); + dstp += 2; + srcp += 2; + w -= 2; + } + + /* final pixel if any */ + if(w) { + Uint16 d = *dstp, s; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + s = (Uint16)prev_sw; +#else + s = (Uint16)(prev_sw >> 16); +#endif + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip - 1; + dstp += dstskip; + } else { + /* source and destination are aligned */ + int w = width; + + /* first odd pixel? */ + if((uintptr_t)srcp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + w--; + } + /* srcp and dstp are now 32-bit aligned */ + + while(w > 1) { + Uint32 sw = *(Uint32 *)srcp; + Uint32 dw = *(Uint32 *)dstp; + *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); + srcp += 2; + dstp += 2; + w -= 2; + } + + /* last odd pixel? */ + if(w) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip; + dstp += dstskip; + } + } +} + +#if GCC_ASMBLIT +/* fast RGB565->RGB565 blending with surface alpha */ +static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + Uint32 s, d; + Uint64 load; + + alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */ + load = alpha; + alpha >>= 3; /* downscale alpha to 5 bits */ + + movq_m2r(load, mm0); /* alpha(0000000A) -> mm0 */ + punpcklwd_r2r(mm0, mm0); /* 00000A0A -> mm0 */ + punpcklwd_r2r(mm0, mm0); /* 0A0A0A0A -> mm0 */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + psllq_i2r(3, mm0); + + /* Setup the 565 color channel masks */ + load = 0x07E007E007E007E0ULL; + movq_m2r(load, mm4); /* MASKGREEN -> mm4 */ + load = 0x001F001F001F001FULL; + movq_m2r(load, mm7); /* MASKBLUE -> mm7 */ + while(height--) { + DUFFS_LOOP_QUATRO2( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = d | d >> 16; + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = d | d >> 16; + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = d | d >> 16; + },{ + movq_m2r((*srcp), mm2);/* 4 src pixels -> mm2 */ + movq_m2r((*dstp), mm3);/* 4 dst pixels -> mm3 */ + + /* red -- does not need a mask since the right shift clears + the uninteresting bits */ + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 [000r 000r 000r 000r] */ + psrlw_i2r(11, mm6); /* mm6 >> 11 -> mm6 [000r 000r 000r 000r] */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* alpha used is actually 11 bits + 11 + 5 = 16 bits, so the sign bits are lost */ + psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + psllw_i2r(11, mm6); /* mm6 << 11 -> mm6 */ + + movq_r2r(mm6, mm1); /* save new reds in dsts */ + + /* green -- process the bits in place */ + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + pand_r2r(mm4, mm5); /* src & MASKGREEN -> mm5 */ + pand_r2r(mm4, mm6); /* dst & MASKGREEN -> mm6 */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* 11 + 11 - 16 = 6 bits, so all the lower uninteresting + bits are gone and the sign bits present */ + psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + + por_r2r(mm6, mm1); /* save new greens in dsts */ + + /* blue */ + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + pand_r2r(mm7, mm5); /* src & MASKBLUE -> mm5[000b 000b 000b 000b] */ + pand_r2r(mm7, mm6); /* dst & MASKBLUE -> mm6[000b 000b 000b 000b] */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* 11 + 5 = 16 bits, so the sign bits are lost and + the interesting bits will need to be MASKed */ + psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + pand_r2r(mm7, mm6); /* mm6 & MASKBLUE -> mm6[000b 000b 000b 000b] */ + + por_r2r(mm6, mm1); /* save new blues in dsts */ + + movq_r2m(mm1, *dstp); /* mm1 -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + srcp += srcskip; + dstp += dstskip; + } + emms(); + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + Uint32 s, d; + Uint64 load; + + alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */ + load = alpha; + alpha >>= 3; /* downscale alpha to 5 bits */ + + movq_m2r(load, mm0); /* alpha(0000000A) -> mm0 */ + punpcklwd_r2r(mm0, mm0); /* 00000A0A -> mm0 */ + punpcklwd_r2r(mm0, mm0); /* 0A0A0A0A -> mm0 */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + psllq_i2r(3, mm0); + + /* Setup the 555 color channel masks */ + load = 0x03E003E003E003E0ULL; + movq_m2r(load, mm4); /* MASKGREEN -> mm4 */ + load = 0x001F001F001F001FULL; + movq_m2r(load, mm7); /* MASKBLUE -> mm7 */ + while(height--) { + DUFFS_LOOP_QUATRO2( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = d | d >> 16; + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = d | d >> 16; + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = d | d >> 16; + },{ + movq_m2r((*srcp), mm2);/* 4 src pixels -> mm2 */ + movq_m2r((*dstp), mm3);/* 4 dst pixels -> mm3 */ + + /* red -- process the bits in place */ + psllq_i2r(5, mm4); /* turn MASKGREEN into MASKRED */ + /* by reusing the GREEN mask we free up another mmx + register to accumulate the result */ + + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + pand_r2r(mm4, mm5); /* src & MASKRED -> mm5 */ + pand_r2r(mm4, mm6); /* dst & MASKRED -> mm6 */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* 11 + 15 - 16 = 10 bits, uninteresting bits will be + cleared by a MASK below */ + psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + pand_r2r(mm4, mm6); /* mm6 & MASKRED -> mm6 */ + + psrlq_i2r(5, mm4); /* turn MASKRED back into MASKGREEN */ + + movq_r2r(mm6, mm1); /* save new reds in dsts */ + + /* green -- process the bits in place */ + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + pand_r2r(mm4, mm5); /* src & MASKGREEN -> mm5 */ + pand_r2r(mm4, mm6); /* dst & MASKGREEN -> mm6 */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* 11 + 10 - 16 = 5 bits, so all the lower uninteresting + bits are gone and the sign bits present */ + psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + + por_r2r(mm6, mm1); /* save new greens in dsts */ + + /* blue */ + movq_r2r(mm2, mm5); /* src -> mm5 */ + movq_r2r(mm3, mm6); /* dst -> mm6 */ + pand_r2r(mm7, mm5); /* src & MASKBLUE -> mm5[000b 000b 000b 000b] */ + pand_r2r(mm7, mm6); /* dst & MASKBLUE -> mm6[000b 000b 000b 000b] */ + + /* blend */ + psubw_r2r(mm6, mm5);/* src - dst -> mm5 */ + pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */ + /* 11 + 5 = 16 bits, so the sign bits are lost and + the interesting bits will need to be MASKed */ + psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */ + paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */ + pand_r2r(mm7, mm6); /* mm6 & MASKBLUE -> mm6[000b 000b 000b 000b] */ + + por_r2r(mm6, mm1); /* save new blues in dsts */ + + movq_r2m(mm1, *dstp);/* mm1 -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + srcp += srcskip; + dstp += dstskip; + } + emms(); + } +} +/* End GCC_ASMBLIT */ + +#elif MSVC_ASMBLIT +/* fast RGB565->RGB565 blending with surface alpha */ +static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + Uint32 s, d; + + __m64 src1, dst1, src2, dst2, gmask, bmask, mm_res, mm_alpha; + + alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ + + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + mm_alpha = _mm_slli_si64(mm_alpha, 3); + + /* Setup the 565 color channel masks */ + gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ + + while(height--) { + DUFFS_LOOP_QUATRO2( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */ + dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */ + + /* red */ + src2 = src1; + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 [000r 000r 000r 000r] */ + + dst2 = dst1; + dst2 = _mm_srli_pi16(dst2, 11); /* dst2 >> 11 -> dst2 [000r 000r 000r 000r] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_slli_pi16(dst2, 11); /* dst2 << 11 -> dst2 */ + + mm_res = dst2; /* RED -> mm_res */ + + /* green -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */ + + /* blue */ + src2 = src1; + src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */ + + *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + Uint32 s, d; + + __m64 src1, dst1, src2, dst2, rmask, gmask, bmask, mm_res, mm_alpha; + + alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ + + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + /* position alpha to allow for mullo and mulhi on diff channels + to reduce the number of operations */ + mm_alpha = _mm_slli_si64(mm_alpha, 3); + + /* Setup the 555 color channel masks */ + rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */ + gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ + + while(height--) { + DUFFS_LOOP_QUATRO2( + { + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + s = *srcp++; + d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + },{ + src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */ + dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */ + + /* red -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, rmask); /* src & MASKRED -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, rmask); /* dst & MASKRED -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, rmask); /* dst2 & MASKRED -> dst2 */ + + mm_res = dst2; /* RED -> mm_res */ + + /* green -- process the bits in place */ + src2 = src1; + src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */ + + dst2 = dst1; + dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */ + + /* blue */ + src2 = src1; /* src -> src2 */ + src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */ + + dst2 = dst1; /* dst -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */ + + /* blend */ + src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */ + dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */ + dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */ + + mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */ + + *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */ + + srcp += 4; + dstp += 4; + }, width); + srcp += srcskip; + dstp += dstskip; + } + _mm_empty(); + } +} +#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */ + +/* fast RGB565->RGB565 blending with surface alpha */ +static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = (Uint16)(d | d >> 16); + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = (Uint16)(d | d >> 16); + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB8888->RGB565 blending with pixel alpha */ +static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp; + unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) { + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp = (Uint16)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast ARGB8888->RGB555 blending with pixel alpha */ +static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + DUFFS_LOOP4({ + unsigned alpha; + Uint32 s = *srcp; + alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) { + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f)); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp = (Uint16)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* General (slow) N->N blending with per-surface alpha */ +static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + if(sA) { + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + DISEMBLE_RGB(dst, dstbpp, dstfmt, Pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } + } +} + +/* General (slow) colorkeyed N->N blending with per-surface alpha */ +static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + Uint32 ckey = srcfmt->colorkey; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel); + if(sA && Pixel != ckey) { + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); + DISEMBLE_RGB(dst, dstbpp, dstfmt, Pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* General (slow) N->N blending with pixel alpha */ +static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + + int srcbpp; + int dstbpp; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + dstbpp = dstfmt->BytesPerPixel; + + /* FIXME: for 8bpp source alpha, this doesn't get opaque values + quite right. for <8bpp source alpha, it gets them very wrong + (check all macros!) + It is unclear whether there is a good general solution that doesn't + need a branch (or a divide). */ + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + unsigned sA; + unsigned dA; + DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); + if(sA) { + DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + + +SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index) +{ + SDL_PixelFormat *sf = surface->format; + SDL_PixelFormat *df = surface->map->dst->format; + + if(sf->Amask == 0) { + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + if(df->BytesPerPixel == 1) + return BlitNto1SurfaceAlphaKey; + else +#if SDL_ALTIVEC_BLITTERS + if (sf->BytesPerPixel == 4 && df->BytesPerPixel == 4 && + !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec()) + return Blit32to32SurfaceAlphaKeyAltivec; + else +#endif + return BlitNtoNSurfaceAlphaKey; + } else { + /* Per-surface alpha blits */ + switch(df->BytesPerPixel) { + case 1: + return BlitNto1SurfaceAlpha; + + case 2: + if(surface->map->identity) { + if(df->Gmask == 0x7e0) + { +#if MMX_ASMBLIT + if(SDL_HasMMX()) + return Blit565to565SurfaceAlphaMMX; + else +#endif + return Blit565to565SurfaceAlpha; + } + else if(df->Gmask == 0x3e0) + { +#if MMX_ASMBLIT + if(SDL_HasMMX()) + return Blit555to555SurfaceAlphaMMX; + else +#endif + return Blit555to555SurfaceAlpha; + } + } + return BlitNtoNSurfaceAlpha; + + case 4: + if(sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask + && sf->BytesPerPixel == 4) + { +#if MMX_ASMBLIT + if(sf->Rshift % 8 == 0 + && sf->Gshift % 8 == 0 + && sf->Bshift % 8 == 0 + && SDL_HasMMX()) + return BlitRGBtoRGBSurfaceAlphaMMX; +#endif + if((sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff) + { +#if SDL_ALTIVEC_BLITTERS + if(!(surface->map->dst->flags & SDL_HWSURFACE) + && SDL_HasAltiVec()) + return BlitRGBtoRGBSurfaceAlphaAltivec; +#endif + return BlitRGBtoRGBSurfaceAlpha; + } + } +#if SDL_ALTIVEC_BLITTERS + if((sf->BytesPerPixel == 4) && + !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec()) + return Blit32to32SurfaceAlphaAltivec; + else +#endif + return BlitNtoNSurfaceAlpha; + + case 3: + default: + return BlitNtoNSurfaceAlpha; + } + } + } else { + /* Per-pixel alpha blits */ + switch(df->BytesPerPixel) { + case 1: + return BlitNto1PixelAlpha; + + case 2: +#if SDL_ALTIVEC_BLITTERS + if(sf->BytesPerPixel == 4 && !(surface->map->dst->flags & SDL_HWSURFACE) && + df->Gmask == 0x7e0 && + df->Bmask == 0x1f && SDL_HasAltiVec()) + return Blit32to565PixelAlphaAltivec; + else +#endif + if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 + && sf->Gmask == 0xff00 + && ((sf->Rmask == 0xff && df->Rmask == 0x1f) + || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { + if(df->Gmask == 0x7e0) + return BlitARGBto565PixelAlpha; + else if(df->Gmask == 0x3e0) + return BlitARGBto555PixelAlpha; + } + return BlitNtoNPixelAlpha; + + case 4: + if(sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask + && sf->BytesPerPixel == 4) + { +#if MMX_ASMBLIT + if(sf->Rshift % 8 == 0 + && sf->Gshift % 8 == 0 + && sf->Bshift % 8 == 0 + && sf->Ashift % 8 == 0 + && sf->Aloss == 0) + { + if(SDL_Has3DNow()) + return BlitRGBtoRGBPixelAlphaMMX3DNOW; + if(SDL_HasMMX()) + return BlitRGBtoRGBPixelAlphaMMX; + } +#endif + if(sf->Amask == 0xff000000) + { +#if SDL_ALTIVEC_BLITTERS + if(!(surface->map->dst->flags & SDL_HWSURFACE) + && SDL_HasAltiVec()) + return BlitRGBtoRGBPixelAlphaAltivec; +#endif + return BlitRGBtoRGBPixelAlpha; + } + } +#if SDL_ALTIVEC_BLITTERS + if (sf->Amask && sf->BytesPerPixel == 4 && + !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec()) + return Blit32to32PixelAlphaAltivec; + else +#endif + return BlitNtoNPixelAlpha; + + case 3: + default: + return BlitNtoNPixelAlpha; + } + } +} + diff --git a/apps/plugins/sdl/src/video/SDL_blit_N.c b/apps/plugins/sdl/src/video/SDL_blit_N.c new file mode 100644 index 0000000000..858cee5ee3 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_blit_N.c @@ -0,0 +1,2492 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_endian.h" +#include "SDL_cpuinfo.h" +#include "SDL_blit.h" + +/* Functions to blit from N-bit surfaces to other surfaces */ + +#if SDL_ALTIVEC_BLITTERS +#if __MWERKS__ +#pragma altivec_model on +#endif +#ifdef HAVE_ALTIVEC_H +#include +#endif +#define assert(X) +#ifdef __MACOSX__ +#include +static size_t GetL3CacheSize( void ) +{ + const char key[] = "hw.l3cachesize"; + u_int64_t result = 0; + size_t typeSize = sizeof( result ); + + + int err = sysctlbyname( key, &result, &typeSize, NULL, 0 ); + if( 0 != err ) return 0; + + return result; +} +#else +static size_t GetL3CacheSize( void ) +{ + /* XXX: Just guess G4 */ + return 2097152; +} +#endif /* __MACOSX__ */ + +#if (defined(__MACOSX__) && (__GNUC__ < 4)) + #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p ) + #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ + (vector unsigned short) ( a,b,c,d,e,f,g,h ) +#else + #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p } + #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ + (vector unsigned short) { a,b,c,d,e,f,g,h } +#endif + +#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F) +#define VSWIZZLE32(a,b,c,d) (vector unsigned char) \ + ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \ + 0x04+a, 0x04+b, 0x04+c, 0x04+d, \ + 0x08+a, 0x08+b, 0x08+c, 0x08+d, \ + 0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d ) + +#define MAKE8888(dstfmt, r, g, b, a) \ + ( ((r<Rshift)&dstfmt->Rmask) | \ + ((g<Gshift)&dstfmt->Gmask) | \ + ((b<Bshift)&dstfmt->Bmask) | \ + ((a<Ashift)&dstfmt->Amask) ) + +/* + * Data Stream Touch...Altivec cache prefetching. + * + * Don't use this on a G5...however, the speed boost is very significant + * on a G4. + */ +#define DST_CHAN_SRC 1 +#define DST_CHAN_DEST 2 + +/* macro to set DST control word value... */ +#define DST_CTRL(size, count, stride) \ + (((size) << 24) | ((count) << 16) | (stride)) + +#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \ + ? vec_lvsl(0, src) \ + : vec_add(vec_lvsl(8, src), vec_splat_u8(8))) + +/* Calculate the permute vector used for 32->32 swizzling */ +static vector unsigned char calc_swizzle32(const SDL_PixelFormat *srcfmt, + const SDL_PixelFormat *dstfmt) +{ + /* + * We have to assume that the bits that aren't used by other + * colors is alpha, and it's one complete byte, since some formats + * leave alpha with a zero mask, but we should still swizzle the bits. + */ + /* ARGB */ + const static struct SDL_PixelFormat default_pixel_format = { + NULL, 0, 0, + 0, 0, 0, 0, + 16, 8, 0, 24, + 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, + 0, 0}; + if (!srcfmt) { + srcfmt = &default_pixel_format; + } + if (!dstfmt) { + dstfmt = &default_pixel_format; + } + const vector unsigned char plus = VECUINT8_LITERAL( + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x04, 0x04, + 0x08, 0x08, 0x08, 0x08, + 0x0C, 0x0C, 0x0C, 0x0C ); + vector unsigned char vswiz; + vector unsigned int srcvec; +#define RESHIFT(X) (3 - ((X) >> 3)) + Uint32 rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift); + Uint32 gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift); + Uint32 bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift); + Uint32 amask; + /* Use zero for alpha if either surface doesn't have alpha */ + if (dstfmt->Amask) { + amask = ((srcfmt->Amask) ? RESHIFT(srcfmt->Ashift) : 0x10) << (dstfmt->Ashift); + } else { + amask = 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^ 0xFFFFFFFF); + } +#undef RESHIFT + ((unsigned int *)(char*)&srcvec)[0] = (rmask | gmask | bmask | amask); + vswiz = vec_add(plus, (vector unsigned char)vec_splat(srcvec, 0)); + return(vswiz); +} + +static void Blit_RGB888_RGB565(SDL_BlitInfo *info); +static void Blit_RGB888_RGB565Altivec(SDL_BlitInfo *info) { + int height = info->d_height; + Uint8 *src = (Uint8 *) info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = (Uint8 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + vector unsigned char valpha = vec_splat_u8(0); + vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL); + vector unsigned char vgmerge = VECUINT8_LITERAL( + 0x00, 0x02, 0x00, 0x06, + 0x00, 0x0a, 0x00, 0x0e, + 0x00, 0x12, 0x00, 0x16, + 0x00, 0x1a, 0x00, 0x1e); + vector unsigned short v1 = vec_splat_u16(1); + vector unsigned short v3 = vec_splat_u16(3); + vector unsigned short v3f = VECUINT16_LITERAL( + 0x003f, 0x003f, 0x003f, 0x003f, + 0x003f, 0x003f, 0x003f, 0x003f); + vector unsigned short vfc = VECUINT16_LITERAL( + 0x00fc, 0x00fc, 0x00fc, 0x00fc, + 0x00fc, 0x00fc, 0x00fc, 0x00fc); + vector unsigned short vf800 = (vector unsigned short)vec_splat_u8(-7); + vf800 = vec_sl(vf800, vec_splat_u16(8)); + + while (height--) { + vector unsigned char valigner; + vector unsigned char voverflow; + vector unsigned char vsrc; + + int width = info->d_width; + int extrawidth; + + /* do scalar until we can align... */ +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, sA; \ + DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \ + sR, sG, sB, sA); \ + *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \ + ((sG << 3) & 0x000007E0) | \ + ((sB >> 3) & 0x0000001F)); \ + dst += 2; \ + src += 4; \ + widthvar--; \ + } + + ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); + + /* After all that work, here's the vector part! */ + extrawidth = (width % 8); /* trailing unaligned stores */ + width -= extrawidth; + vsrc = vec_ld(0, src); + valigner = VEC_ALIGNER(src); + + while (width) { + vector unsigned short vpixel, vrpixel, vgpixel, vbpixel; + vector unsigned int vsrc1, vsrc2; + vector unsigned char vdst; + + voverflow = vec_ld(15, src); + vsrc = vec_perm(vsrc, voverflow, valigner); + vsrc1 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute); + src += 16; + vsrc = voverflow; + voverflow = vec_ld(15, src); + vsrc = vec_perm(vsrc, voverflow, valigner); + vsrc2 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute); + /* 1555 */ + vpixel = (vector unsigned short)vec_packpx(vsrc1, vsrc2); + vgpixel = (vector unsigned short)vec_perm(vsrc1, vsrc2, vgmerge); + vgpixel = vec_and(vgpixel, vfc); + vgpixel = vec_sl(vgpixel, v3); + vrpixel = vec_sl(vpixel, v1); + vrpixel = vec_and(vrpixel, vf800); + vbpixel = vec_and(vpixel, v3f); + vdst = vec_or((vector unsigned char)vrpixel, (vector unsigned char)vgpixel); + /* 565 */ + vdst = vec_or(vdst, (vector unsigned char)vbpixel); + vec_st(vdst, 0, dst); + + width -= 8; + src += 16; + dst += 16; + vsrc = voverflow; + } + + assert(width == 0); + + /* do scalar until we can align... */ + ONE_PIXEL_BLEND((extrawidth), extrawidth); +#undef ONE_PIXEL_BLEND + + src += srcskip; /* move to next row, accounting for pitch. */ + dst += dstskip; + } + + +} + +static void Blit_RGB565_32Altivec(SDL_BlitInfo *info) { + int height = info->d_height; + Uint8 *src = (Uint8 *) info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = (Uint8 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + unsigned alpha; + vector unsigned char valpha; + vector unsigned char vpermute; + vector unsigned short vf800; + vector unsigned int v8 = vec_splat_u32(8); + vector unsigned int v16 = vec_add(v8, v8); + vector unsigned short v2 = vec_splat_u16(2); + vector unsigned short v3 = vec_splat_u16(3); + /* + 0x10 - 0x1f is the alpha + 0x00 - 0x0e evens are the red + 0x01 - 0x0f odds are zero + */ + vector unsigned char vredalpha1 = VECUINT8_LITERAL( + 0x10, 0x00, 0x01, 0x01, + 0x10, 0x02, 0x01, 0x01, + 0x10, 0x04, 0x01, 0x01, + 0x10, 0x06, 0x01, 0x01 + ); + vector unsigned char vredalpha2 = (vector unsigned char) ( + vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16)) + ); + /* + 0x00 - 0x0f is ARxx ARxx ARxx ARxx + 0x11 - 0x0f odds are blue + */ + vector unsigned char vblue1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x02, 0x11, + 0x04, 0x05, 0x06, 0x13, + 0x08, 0x09, 0x0a, 0x15, + 0x0c, 0x0d, 0x0e, 0x17 + ); + vector unsigned char vblue2 = (vector unsigned char)( + vec_add((vector unsigned int)vblue1, v8) + ); + /* + 0x00 - 0x0f is ARxB ARxB ARxB ARxB + 0x10 - 0x0e evens are green + */ + vector unsigned char vgreen1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x10, 0x03, + 0x04, 0x05, 0x12, 0x07, + 0x08, 0x09, 0x14, 0x0b, + 0x0c, 0x0d, 0x16, 0x0f + ); + vector unsigned char vgreen2 = (vector unsigned char)( + vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8)) + ); + + + assert(srcfmt->BytesPerPixel == 2); + assert(dstfmt->BytesPerPixel == 4); + + vf800 = (vector unsigned short)vec_splat_u8(-7); + vf800 = vec_sl(vf800, vec_splat_u16(8)); + + if (dstfmt->Amask && srcfmt->alpha) { + ((unsigned char *)&valpha)[0] = alpha = srcfmt->alpha; + valpha = vec_splat(valpha, 0); + } else { + alpha = 0; + valpha = vec_splat_u8(0); + } + + vpermute = calc_swizzle32(NULL, dstfmt); + while (height--) { + vector unsigned char valigner; + vector unsigned char voverflow; + vector unsigned char vsrc; + + int width = info->d_width; + int extrawidth; + + /* do scalar until we can align... */ +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + unsigned sR, sG, sB; \ + unsigned short Pixel = *((unsigned short *)src); \ + sR = (Pixel >> 8) & 0xf8; \ + sG = (Pixel >> 3) & 0xfc; \ + sB = (Pixel << 3) & 0xf8; \ + ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ + src += 2; \ + dst += 4; \ + widthvar--; \ + } + ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); + + /* After all that work, here's the vector part! */ + extrawidth = (width % 8); /* trailing unaligned stores */ + width -= extrawidth; + vsrc = vec_ld(0, src); + valigner = VEC_ALIGNER(src); + + while (width) { + vector unsigned short vR, vG, vB; + vector unsigned char vdst1, vdst2; + + voverflow = vec_ld(15, src); + vsrc = vec_perm(vsrc, voverflow, valigner); + + vR = vec_and((vector unsigned short)vsrc, vf800); + vB = vec_sl((vector unsigned short)vsrc, v3); + vG = vec_sl(vB, v2); + + vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); + vdst1 = vec_perm(vdst1, valpha, vpermute); + vec_st(vdst1, 0, dst); + + vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2); + vdst2 = vec_perm(vdst2, valpha, vpermute); + vec_st(vdst2, 16, dst); + + width -= 8; + dst += 32; + src += 16; + vsrc = voverflow; + } + + assert(width == 0); + + + /* do scalar until we can align... */ + ONE_PIXEL_BLEND((extrawidth), extrawidth); +#undef ONE_PIXEL_BLEND + + src += srcskip; /* move to next row, accounting for pitch. */ + dst += dstskip; + } + +} + + +static void Blit_RGB555_32Altivec(SDL_BlitInfo *info) { + int height = info->d_height; + Uint8 *src = (Uint8 *) info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = (Uint8 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + unsigned alpha; + vector unsigned char valpha; + vector unsigned char vpermute; + vector unsigned short vf800; + vector unsigned int v8 = vec_splat_u32(8); + vector unsigned int v16 = vec_add(v8, v8); + vector unsigned short v1 = vec_splat_u16(1); + vector unsigned short v3 = vec_splat_u16(3); + /* + 0x10 - 0x1f is the alpha + 0x00 - 0x0e evens are the red + 0x01 - 0x0f odds are zero + */ + vector unsigned char vredalpha1 = VECUINT8_LITERAL( + 0x10, 0x00, 0x01, 0x01, + 0x10, 0x02, 0x01, 0x01, + 0x10, 0x04, 0x01, 0x01, + 0x10, 0x06, 0x01, 0x01 + ); + vector unsigned char vredalpha2 = (vector unsigned char)( + vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16)) + ); + /* + 0x00 - 0x0f is ARxx ARxx ARxx ARxx + 0x11 - 0x0f odds are blue + */ + vector unsigned char vblue1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x02, 0x11, + 0x04, 0x05, 0x06, 0x13, + 0x08, 0x09, 0x0a, 0x15, + 0x0c, 0x0d, 0x0e, 0x17 + ); + vector unsigned char vblue2 = (vector unsigned char)( + vec_add((vector unsigned int)vblue1, v8) + ); + /* + 0x00 - 0x0f is ARxB ARxB ARxB ARxB + 0x10 - 0x0e evens are green + */ + vector unsigned char vgreen1 = VECUINT8_LITERAL( + 0x00, 0x01, 0x10, 0x03, + 0x04, 0x05, 0x12, 0x07, + 0x08, 0x09, 0x14, 0x0b, + 0x0c, 0x0d, 0x16, 0x0f + ); + vector unsigned char vgreen2 = (vector unsigned char)( + vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8)) + ); + + + assert(srcfmt->BytesPerPixel == 2); + assert(dstfmt->BytesPerPixel == 4); + + vf800 = (vector unsigned short)vec_splat_u8(-7); + vf800 = vec_sl(vf800, vec_splat_u16(8)); + + if (dstfmt->Amask && srcfmt->alpha) { + ((unsigned char *)&valpha)[0] = alpha = srcfmt->alpha; + valpha = vec_splat(valpha, 0); + } else { + alpha = 0; + valpha = vec_splat_u8(0); + } + + vpermute = calc_swizzle32(NULL, dstfmt); + while (height--) { + vector unsigned char valigner; + vector unsigned char voverflow; + vector unsigned char vsrc; + + int width = info->d_width; + int extrawidth; + + /* do scalar until we can align... */ +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + unsigned sR, sG, sB; \ + unsigned short Pixel = *((unsigned short *)src); \ + sR = (Pixel >> 7) & 0xf8; \ + sG = (Pixel >> 2) & 0xf8; \ + sB = (Pixel << 3) & 0xf8; \ + ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ + src += 2; \ + dst += 4; \ + widthvar--; \ + } + ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); + + /* After all that work, here's the vector part! */ + extrawidth = (width % 8); /* trailing unaligned stores */ + width -= extrawidth; + vsrc = vec_ld(0, src); + valigner = VEC_ALIGNER(src); + + while (width) { + vector unsigned short vR, vG, vB; + vector unsigned char vdst1, vdst2; + + voverflow = vec_ld(15, src); + vsrc = vec_perm(vsrc, voverflow, valigner); + + vR = vec_and(vec_sl((vector unsigned short)vsrc,v1), vf800); + vB = vec_sl((vector unsigned short)vsrc, v3); + vG = vec_sl(vB, v3); + + vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); + vdst1 = vec_perm(vdst1, valpha, vpermute); + vec_st(vdst1, 0, dst); + + vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2); + vdst2 = vec_perm(vdst2, valpha, vpermute); + vec_st(vdst2, 16, dst); + + width -= 8; + dst += 32; + src += 16; + vsrc = voverflow; + } + + assert(width == 0); + + + /* do scalar until we can align... */ + ONE_PIXEL_BLEND((extrawidth), extrawidth); +#undef ONE_PIXEL_BLEND + + src += srcskip; /* move to next row, accounting for pitch. */ + dst += dstskip; + } + +} + +static void BlitNtoNKey(SDL_BlitInfo *info); +static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info); +static void Blit32to32KeyAltivec(SDL_BlitInfo *info) +{ + int height = info->d_height; + Uint32 *srcp = (Uint32 *) info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dstp = (Uint32 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + int srcbpp = srcfmt->BytesPerPixel; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp = dstfmt->BytesPerPixel; + int copy_alpha = (srcfmt->Amask && dstfmt->Amask); + unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0; + Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; + Uint32 ckey = info->src->colorkey; + vector unsigned int valpha; + vector unsigned char vpermute; + vector unsigned char vzero; + vector unsigned int vckey; + vector unsigned int vrgbmask; + vpermute = calc_swizzle32(srcfmt, dstfmt); + if (info->d_width < 16) { + if(copy_alpha) { + BlitNtoNKeyCopyAlpha(info); + } else { + BlitNtoNKey(info); + } + return; + } + vzero = vec_splat_u8(0); + if (alpha) { + ((unsigned char *)&valpha)[0] = (unsigned char)alpha; + valpha = (vector unsigned int)vec_splat((vector unsigned char)valpha, 0); + } else { + valpha = (vector unsigned int)vzero; + } + ckey &= rgbmask; + ((unsigned int *)(char*)&vckey)[0] = ckey; + vckey = vec_splat(vckey, 0); + ((unsigned int *)(char*)&vrgbmask)[0] = rgbmask; + vrgbmask = vec_splat(vrgbmask, 0); + + while (height--) { +#define ONE_PIXEL_BLEND(condition, widthvar) \ + if (copy_alpha) { \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, sA; \ + DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \ + sR, sG, sB, sA); \ + if ( (Pixel & rgbmask) != ckey ) { \ + ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ + sR, sG, sB, sA); \ + } \ + dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \ + srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \ + widthvar--; \ + } \ + } else { \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB; \ + RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \ + if ( Pixel != ckey ) { \ + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \ + ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ + sR, sG, sB, alpha); \ + } \ + dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \ + srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \ + widthvar--; \ + } \ + } + int width = info->d_width; + ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); + assert(width > 0); + if (width > 0) { + int extrawidth = (width % 4); + vector unsigned char valigner = VEC_ALIGNER(srcp); + vector unsigned int vs = vec_ld(0, srcp); + width -= extrawidth; + assert(width >= 4); + while (width) { + vector unsigned char vsel; + vector unsigned int vd; + vector unsigned int voverflow = vec_ld(15, srcp); + /* load the source vec */ + vs = vec_perm(vs, voverflow, valigner); + /* vsel is set for items that match the key */ + vsel = (vector unsigned char)vec_and(vs, vrgbmask); + vsel = (vector unsigned char)vec_cmpeq(vs, vckey); + /* permute the src vec to the dest format */ + vs = vec_perm(vs, valpha, vpermute); + /* load the destination vec */ + vd = vec_ld(0, dstp); + /* select the source and dest into vs */ + vd = (vector unsigned int)vec_sel((vector unsigned char)vs, (vector unsigned char)vd, vsel); + + vec_st(vd, 0, dstp); + srcp += 4; + width -= 4; + dstp += 4; + vs = voverflow; + } + ONE_PIXEL_BLEND((extrawidth), extrawidth); +#undef ONE_PIXEL_BLEND + srcp += srcskip >> 2; + dstp += dstskip >> 2; + } + } +} + +/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */ +/* Use this on a G5 */ +static void ConvertAltivec32to32_noprefetch(SDL_BlitInfo *info) +{ + int height = info->d_height; + Uint32 *src = (Uint32 *) info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dst = (Uint32 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + vector unsigned int vzero = vec_splat_u32(0); + vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt); + if (dstfmt->Amask && !srcfmt->Amask) { + if (srcfmt->alpha) { + vector unsigned char valpha; + ((unsigned char *)&valpha)[0] = srcfmt->alpha; + vzero = (vector unsigned int)vec_splat(valpha, 0); + } + } + + assert(srcfmt->BytesPerPixel == 4); + assert(dstfmt->BytesPerPixel == 4); + + while (height--) { + vector unsigned char valigner; + vector unsigned int vbits; + vector unsigned int voverflow; + Uint32 bits; + Uint8 r, g, b, a; + + int width = info->d_width; + int extrawidth; + + /* do scalar until we can align... */ + while ((UNALIGNED_PTR(dst)) && (width)) { + bits = *(src++); + RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + *(dst++) = MAKE8888(dstfmt, r, g, b, a); + width--; + } + + /* After all that work, here's the vector part! */ + extrawidth = (width % 4); + width -= extrawidth; + valigner = VEC_ALIGNER(src); + vbits = vec_ld(0, src); + + while (width) { + voverflow = vec_ld(15, src); + src += 4; + width -= 4; + vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ + vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ + vec_st(vbits, 0, dst); /* store it back out. */ + dst += 4; + vbits = voverflow; + } + + assert(width == 0); + + /* cover pixels at the end of the row that didn't fit in 16 bytes. */ + while (extrawidth) { + bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ + RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + *(dst++) = MAKE8888(dstfmt, r, g, b, a); + extrawidth--; + } + + src += srcskip >> 2; /* move to next row, accounting for pitch. */ + dst += dstskip >> 2; + } + +} + +/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */ +/* Use this on a G4 */ +static void ConvertAltivec32to32_prefetch(SDL_BlitInfo *info) +{ + const int scalar_dst_lead = sizeof (Uint32) * 4; + const int vector_dst_lead = sizeof (Uint32) * 16; + + int height = info->d_height; + Uint32 *src = (Uint32 *) info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dst = (Uint32 *) info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + vector unsigned int vzero = vec_splat_u32(0); + vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt); + if (dstfmt->Amask && !srcfmt->Amask) { + if (srcfmt->alpha) { + vector unsigned char valpha; + ((unsigned char *)&valpha)[0] = srcfmt->alpha; + vzero = (vector unsigned int)vec_splat(valpha, 0); + } + } + + assert(srcfmt->BytesPerPixel == 4); + assert(dstfmt->BytesPerPixel == 4); + + while (height--) { + vector unsigned char valigner; + vector unsigned int vbits; + vector unsigned int voverflow; + Uint32 bits; + Uint8 r, g, b, a; + + int width = info->d_width; + int extrawidth; + + /* do scalar until we can align... */ + while ((UNALIGNED_PTR(dst)) && (width)) { + vec_dstt(src+scalar_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_SRC); + vec_dstst(dst+scalar_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_DEST); + bits = *(src++); + RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + *(dst++) = MAKE8888(dstfmt, r, g, b, a); + width--; + } + + /* After all that work, here's the vector part! */ + extrawidth = (width % 4); + width -= extrawidth; + valigner = VEC_ALIGNER(src); + vbits = vec_ld(0, src); + + while (width) { + vec_dstt(src+vector_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_SRC); + vec_dstst(dst+vector_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_DEST); + voverflow = vec_ld(15, src); + src += 4; + width -= 4; + vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ + vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ + vec_st(vbits, 0, dst); /* store it back out. */ + dst += 4; + vbits = voverflow; + } + + assert(width == 0); + + /* cover pixels at the end of the row that didn't fit in 16 bytes. */ + while (extrawidth) { + bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ + RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + *(dst++) = MAKE8888(dstfmt, r, g, b, a); + extrawidth--; + } + + src += srcskip >> 2; /* move to next row, accounting for pitch. */ + dst += dstskip >> 2; + } + + vec_dss(DST_CHAN_SRC); + vec_dss(DST_CHAN_DEST); +} + +static Uint32 GetBlitFeatures( void ) +{ + static Uint32 features = 0xffffffff; + if (features == 0xffffffff) { + /* Provide an override for testing .. */ + char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES"); + if (override) { + features = 0; + SDL_sscanf(override, "%u", &features); + } else { + features = ( 0 + /* Feature 1 is has-MMX */ + | ((SDL_HasMMX()) ? 1 : 0) + /* Feature 2 is has-AltiVec */ + | ((SDL_HasAltiVec()) ? 2 : 0) + /* Feature 4 is dont-use-prefetch */ + /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */ + | ((GetL3CacheSize() == 0) ? 4 : 0) + ); + } + } + return features; +} +#if __MWERKS__ +#pragma altivec_model off +#endif +#else +/* Feature 1 is has-MMX */ +#define GetBlitFeatures() ((Uint32)(SDL_HasMMX() ? 1 : 0)) +#endif + +/* This is now endian dependent */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define HI 1 +#define LO 0 +#else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */ +#define HI 0 +#define LO 1 +#endif + +#if SDL_HERMES_BLITTERS + +/* Heheheh, we coerce Hermes into using SDL blit information */ +#define X86_ASSEMBLER +#define HermesConverterInterface SDL_BlitInfo +#define HermesClearInterface void +#define STACKCALL + +#include "../hermes/HeadMMX.h" +#include "../hermes/HeadX86.h" + +#else + +/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ +#define RGB888_RGB332(dst, src) { \ + dst = (Uint8)((((src)&0x00E00000)>>16)| \ + (((src)&0x0000E000)>>11)| \ + (((src)&0x000000C0)>>6)); \ +} +static void Blit_RGB888_index8(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + if ( map == NULL ) { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + RGB888_RGB332(*dst++, *src); + , width); +#else + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(*dst++, *src); + ++src; + case 2: + RGB888_RGB332(*dst++, *src); + ++src; + case 1: + RGB888_RGB332(*dst++, *src); + ++src; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } else { + int Pixel; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + , width); +#else + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + case 2: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + case 1: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } +} +/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */ +#define RGB888_RGB555(dst, src) { \ + *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \ + (((*src)&0x0000F800)>>6)| \ + (((*src)&0x000000F8)>>3)); \ +} +#define RGB888_RGB555_TWO(dst, src) { \ + *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \ + (((src[HI])&0x0000F800)>>6)| \ + (((src[HI])&0x000000F8)>>3))<<16)| \ + (((src[LO])&0x00F80000)>>9)| \ + (((src[LO])&0x0000F800)>>6)| \ + (((src[LO])&0x000000F8)>>3); \ +} +static void Blit_RGB888_RGB555(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + Uint16 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB555(dst, src); + ++src; + ++dst; + , width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + RGB888_RGB555(dst, src); + ++src; + ++dst; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB555(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB555(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB555(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB555(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} +/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */ +#define RGB888_RGB565(dst, src) { \ + *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \ + (((*src)&0x0000FC00)>>5)| \ + (((*src)&0x000000F8)>>3)); \ +} +#define RGB888_RGB565_TWO(dst, src) { \ + *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \ + (((src[HI])&0x0000FC00)>>5)| \ + (((src[HI])&0x000000F8)>>3))<<16)| \ + (((src[LO])&0x00F80000)>>8)| \ + (((src[LO])&0x0000FC00)>>5)| \ + (((src[LO])&0x000000F8)>>3); \ +} +static void Blit_RGB888_RGB565(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + Uint16 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB565(dst, src); + ++src; + ++dst; + , width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + RGB888_RGB565(dst, src); + ++src; + ++dst; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB565(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB565(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB565(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB565(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} + +#endif /* SDL_HERMES_BLITTERS */ + + +/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */ +#define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1]) +static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + Uint32 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint8 *)info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + { + *dst++ = RGB565_32(dst, src, map); + src += 2; + }, + width); + src += srcskip; + dst += dstskip; + } +#else + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *dst++ = RGB565_32(dst, src, map); + src += 2; + case 2: + *dst++ = RGB565_32(dst, src, map); + src += 2; + case 1: + *dst++ = RGB565_32(dst, src, map); + src += 2; + break; + } + src += srcskip; + dst += dstskip; + } +#endif /* USE_DUFFS_LOOP */ +} + +/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */ +static const Uint32 RGB565_ARGB8888_LUT[512] = { + 0x00000000, 0xff000000, 0x00000008, 0xff002000, + 0x00000010, 0xff004000, 0x00000018, 0xff006100, + 0x00000020, 0xff008100, 0x00000029, 0xff00a100, + 0x00000031, 0xff00c200, 0x00000039, 0xff00e200, + 0x00000041, 0xff080000, 0x0000004a, 0xff082000, + 0x00000052, 0xff084000, 0x0000005a, 0xff086100, + 0x00000062, 0xff088100, 0x0000006a, 0xff08a100, + 0x00000073, 0xff08c200, 0x0000007b, 0xff08e200, + 0x00000083, 0xff100000, 0x0000008b, 0xff102000, + 0x00000094, 0xff104000, 0x0000009c, 0xff106100, + 0x000000a4, 0xff108100, 0x000000ac, 0xff10a100, + 0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200, + 0x000000c5, 0xff180000, 0x000000cd, 0xff182000, + 0x000000d5, 0xff184000, 0x000000de, 0xff186100, + 0x000000e6, 0xff188100, 0x000000ee, 0xff18a100, + 0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200, + 0x00000400, 0xff200000, 0x00000408, 0xff202000, + 0x00000410, 0xff204000, 0x00000418, 0xff206100, + 0x00000420, 0xff208100, 0x00000429, 0xff20a100, + 0x00000431, 0xff20c200, 0x00000439, 0xff20e200, + 0x00000441, 0xff290000, 0x0000044a, 0xff292000, + 0x00000452, 0xff294000, 0x0000045a, 0xff296100, + 0x00000462, 0xff298100, 0x0000046a, 0xff29a100, + 0x00000473, 0xff29c200, 0x0000047b, 0xff29e200, + 0x00000483, 0xff310000, 0x0000048b, 0xff312000, + 0x00000494, 0xff314000, 0x0000049c, 0xff316100, + 0x000004a4, 0xff318100, 0x000004ac, 0xff31a100, + 0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200, + 0x000004c5, 0xff390000, 0x000004cd, 0xff392000, + 0x000004d5, 0xff394000, 0x000004de, 0xff396100, + 0x000004e6, 0xff398100, 0x000004ee, 0xff39a100, + 0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200, + 0x00000800, 0xff410000, 0x00000808, 0xff412000, + 0x00000810, 0xff414000, 0x00000818, 0xff416100, + 0x00000820, 0xff418100, 0x00000829, 0xff41a100, + 0x00000831, 0xff41c200, 0x00000839, 0xff41e200, + 0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000, + 0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100, + 0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100, + 0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200, + 0x00000883, 0xff520000, 0x0000088b, 0xff522000, + 0x00000894, 0xff524000, 0x0000089c, 0xff526100, + 0x000008a4, 0xff528100, 0x000008ac, 0xff52a100, + 0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200, + 0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000, + 0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100, + 0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100, + 0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200, + 0x00000c00, 0xff620000, 0x00000c08, 0xff622000, + 0x00000c10, 0xff624000, 0x00000c18, 0xff626100, + 0x00000c20, 0xff628100, 0x00000c29, 0xff62a100, + 0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200, + 0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000, + 0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100, + 0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100, + 0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200, + 0x00000c83, 0xff730000, 0x00000c8b, 0xff732000, + 0x00000c94, 0xff734000, 0x00000c9c, 0xff736100, + 0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100, + 0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200, + 0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000, + 0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100, + 0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100, + 0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200, + 0x00001000, 0xff830000, 0x00001008, 0xff832000, + 0x00001010, 0xff834000, 0x00001018, 0xff836100, + 0x00001020, 0xff838100, 0x00001029, 0xff83a100, + 0x00001031, 0xff83c200, 0x00001039, 0xff83e200, + 0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000, + 0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100, + 0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100, + 0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200, + 0x00001083, 0xff940000, 0x0000108b, 0xff942000, + 0x00001094, 0xff944000, 0x0000109c, 0xff946100, + 0x000010a4, 0xff948100, 0x000010ac, 0xff94a100, + 0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200, + 0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000, + 0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100, + 0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100, + 0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200, + 0x00001400, 0xffa40000, 0x00001408, 0xffa42000, + 0x00001410, 0xffa44000, 0x00001418, 0xffa46100, + 0x00001420, 0xffa48100, 0x00001429, 0xffa4a100, + 0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200, + 0x00001441, 0xffac0000, 0x0000144a, 0xffac2000, + 0x00001452, 0xffac4000, 0x0000145a, 0xffac6100, + 0x00001462, 0xffac8100, 0x0000146a, 0xffaca100, + 0x00001473, 0xffacc200, 0x0000147b, 0xfface200, + 0x00001483, 0xffb40000, 0x0000148b, 0xffb42000, + 0x00001494, 0xffb44000, 0x0000149c, 0xffb46100, + 0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100, + 0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200, + 0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000, + 0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100, + 0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100, + 0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200, + 0x00001800, 0xffc50000, 0x00001808, 0xffc52000, + 0x00001810, 0xffc54000, 0x00001818, 0xffc56100, + 0x00001820, 0xffc58100, 0x00001829, 0xffc5a100, + 0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200, + 0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000, + 0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100, + 0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100, + 0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200, + 0x00001883, 0xffd50000, 0x0000188b, 0xffd52000, + 0x00001894, 0xffd54000, 0x0000189c, 0xffd56100, + 0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100, + 0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200, + 0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000, + 0x000018d5, 0xffde4000, 0x000018de, 0xffde6100, + 0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100, + 0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200, + 0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000, + 0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100, + 0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100, + 0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200, + 0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000, + 0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100, + 0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100, + 0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200, + 0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000, + 0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100, + 0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100, + 0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200, + 0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000, + 0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100, + 0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100, + 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200 +}; +static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_ARGB8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */ +static const Uint32 RGB565_ABGR8888_LUT[512] = { + 0xff000000, 0x00000000, 0xff080000, 0x00002000, + 0xff100000, 0x00004000, 0xff180000, 0x00006100, + 0xff200000, 0x00008100, 0xff290000, 0x0000a100, + 0xff310000, 0x0000c200, 0xff390000, 0x0000e200, + 0xff410000, 0x00000008, 0xff4a0000, 0x00002008, + 0xff520000, 0x00004008, 0xff5a0000, 0x00006108, + 0xff620000, 0x00008108, 0xff6a0000, 0x0000a108, + 0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208, + 0xff830000, 0x00000010, 0xff8b0000, 0x00002010, + 0xff940000, 0x00004010, 0xff9c0000, 0x00006110, + 0xffa40000, 0x00008110, 0xffac0000, 0x0000a110, + 0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210, + 0xffc50000, 0x00000018, 0xffcd0000, 0x00002018, + 0xffd50000, 0x00004018, 0xffde0000, 0x00006118, + 0xffe60000, 0x00008118, 0xffee0000, 0x0000a118, + 0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218, + 0xff000400, 0x00000020, 0xff080400, 0x00002020, + 0xff100400, 0x00004020, 0xff180400, 0x00006120, + 0xff200400, 0x00008120, 0xff290400, 0x0000a120, + 0xff310400, 0x0000c220, 0xff390400, 0x0000e220, + 0xff410400, 0x00000029, 0xff4a0400, 0x00002029, + 0xff520400, 0x00004029, 0xff5a0400, 0x00006129, + 0xff620400, 0x00008129, 0xff6a0400, 0x0000a129, + 0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229, + 0xff830400, 0x00000031, 0xff8b0400, 0x00002031, + 0xff940400, 0x00004031, 0xff9c0400, 0x00006131, + 0xffa40400, 0x00008131, 0xffac0400, 0x0000a131, + 0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231, + 0xffc50400, 0x00000039, 0xffcd0400, 0x00002039, + 0xffd50400, 0x00004039, 0xffde0400, 0x00006139, + 0xffe60400, 0x00008139, 0xffee0400, 0x0000a139, + 0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239, + 0xff000800, 0x00000041, 0xff080800, 0x00002041, + 0xff100800, 0x00004041, 0xff180800, 0x00006141, + 0xff200800, 0x00008141, 0xff290800, 0x0000a141, + 0xff310800, 0x0000c241, 0xff390800, 0x0000e241, + 0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a, + 0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a, + 0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a, + 0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a, + 0xff830800, 0x00000052, 0xff8b0800, 0x00002052, + 0xff940800, 0x00004052, 0xff9c0800, 0x00006152, + 0xffa40800, 0x00008152, 0xffac0800, 0x0000a152, + 0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252, + 0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a, + 0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a, + 0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a, + 0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a, + 0xff000c00, 0x00000062, 0xff080c00, 0x00002062, + 0xff100c00, 0x00004062, 0xff180c00, 0x00006162, + 0xff200c00, 0x00008162, 0xff290c00, 0x0000a162, + 0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262, + 0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a, + 0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a, + 0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a, + 0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a, + 0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073, + 0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173, + 0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173, + 0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273, + 0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b, + 0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b, + 0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b, + 0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b, + 0xff001000, 0x00000083, 0xff081000, 0x00002083, + 0xff101000, 0x00004083, 0xff181000, 0x00006183, + 0xff201000, 0x00008183, 0xff291000, 0x0000a183, + 0xff311000, 0x0000c283, 0xff391000, 0x0000e283, + 0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b, + 0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b, + 0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b, + 0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b, + 0xff831000, 0x00000094, 0xff8b1000, 0x00002094, + 0xff941000, 0x00004094, 0xff9c1000, 0x00006194, + 0xffa41000, 0x00008194, 0xffac1000, 0x0000a194, + 0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294, + 0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c, + 0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c, + 0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c, + 0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c, + 0xff001400, 0x000000a4, 0xff081400, 0x000020a4, + 0xff101400, 0x000040a4, 0xff181400, 0x000061a4, + 0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4, + 0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4, + 0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac, + 0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac, + 0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac, + 0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac, + 0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4, + 0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4, + 0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4, + 0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4, + 0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd, + 0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd, + 0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd, + 0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd, + 0xff001800, 0x000000c5, 0xff081800, 0x000020c5, + 0xff101800, 0x000040c5, 0xff181800, 0x000061c5, + 0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5, + 0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5, + 0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd, + 0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd, + 0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd, + 0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd, + 0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5, + 0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5, + 0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5, + 0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5, + 0xffc51800, 0x000000de, 0xffcd1800, 0x000020de, + 0xffd51800, 0x000040de, 0xffde1800, 0x000061de, + 0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de, + 0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de, + 0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6, + 0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6, + 0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6, + 0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6, + 0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee, + 0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee, + 0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee, + 0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee, + 0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6, + 0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6, + 0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6, + 0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6, + 0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff, + 0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff, + 0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff, + 0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff +}; +static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_ABGR8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */ +static const Uint32 RGB565_RGBA8888_LUT[512] = { + 0x000000ff, 0x00000000, 0x000008ff, 0x00200000, + 0x000010ff, 0x00400000, 0x000018ff, 0x00610000, + 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000, + 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000, + 0x000041ff, 0x08000000, 0x00004aff, 0x08200000, + 0x000052ff, 0x08400000, 0x00005aff, 0x08610000, + 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000, + 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000, + 0x000083ff, 0x10000000, 0x00008bff, 0x10200000, + 0x000094ff, 0x10400000, 0x00009cff, 0x10610000, + 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000, + 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000, + 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000, + 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000, + 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000, + 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000, + 0x000400ff, 0x20000000, 0x000408ff, 0x20200000, + 0x000410ff, 0x20400000, 0x000418ff, 0x20610000, + 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000, + 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000, + 0x000441ff, 0x29000000, 0x00044aff, 0x29200000, + 0x000452ff, 0x29400000, 0x00045aff, 0x29610000, + 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000, + 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000, + 0x000483ff, 0x31000000, 0x00048bff, 0x31200000, + 0x000494ff, 0x31400000, 0x00049cff, 0x31610000, + 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000, + 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000, + 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000, + 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000, + 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000, + 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000, + 0x000800ff, 0x41000000, 0x000808ff, 0x41200000, + 0x000810ff, 0x41400000, 0x000818ff, 0x41610000, + 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000, + 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000, + 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000, + 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000, + 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000, + 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000, + 0x000883ff, 0x52000000, 0x00088bff, 0x52200000, + 0x000894ff, 0x52400000, 0x00089cff, 0x52610000, + 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000, + 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000, + 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000, + 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000, + 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000, + 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000, + 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000, + 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000, + 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000, + 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000, + 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000, + 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000, + 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000, + 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000, + 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000, + 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000, + 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000, + 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000, + 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000, + 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000, + 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000, + 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000, + 0x001000ff, 0x83000000, 0x001008ff, 0x83200000, + 0x001010ff, 0x83400000, 0x001018ff, 0x83610000, + 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000, + 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000, + 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000, + 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000, + 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000, + 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000, + 0x001083ff, 0x94000000, 0x00108bff, 0x94200000, + 0x001094ff, 0x94400000, 0x00109cff, 0x94610000, + 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000, + 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000, + 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000, + 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000, + 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000, + 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000, + 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000, + 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000, + 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000, + 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000, + 0x001441ff, 0xac000000, 0x00144aff, 0xac200000, + 0x001452ff, 0xac400000, 0x00145aff, 0xac610000, + 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000, + 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000, + 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000, + 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000, + 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000, + 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000, + 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000, + 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000, + 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000, + 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000, + 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000, + 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000, + 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000, + 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000, + 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000, + 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000, + 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000, + 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000, + 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000, + 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000, + 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000, + 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000, + 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000, + 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000, + 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000, + 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000, + 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000, + 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000, + 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000, + 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000, + 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000, + 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000, + 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000, + 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000, + 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000, + 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000, + 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000, + 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000, + 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000, + 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000, + 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000, + 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000, +}; +static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_RGBA8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */ +static const Uint32 RGB565_BGRA8888_LUT[512] = { + 0x00000000, 0x000000ff, 0x08000000, 0x002000ff, + 0x10000000, 0x004000ff, 0x18000000, 0x006100ff, + 0x20000000, 0x008100ff, 0x29000000, 0x00a100ff, + 0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff, + 0x41000000, 0x000008ff, 0x4a000000, 0x002008ff, + 0x52000000, 0x004008ff, 0x5a000000, 0x006108ff, + 0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff, + 0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff, + 0x83000000, 0x000010ff, 0x8b000000, 0x002010ff, + 0x94000000, 0x004010ff, 0x9c000000, 0x006110ff, + 0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff, + 0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff, + 0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff, + 0xd5000000, 0x004018ff, 0xde000000, 0x006118ff, + 0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff, + 0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff, + 0x00040000, 0x000020ff, 0x08040000, 0x002020ff, + 0x10040000, 0x004020ff, 0x18040000, 0x006120ff, + 0x20040000, 0x008120ff, 0x29040000, 0x00a120ff, + 0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff, + 0x41040000, 0x000029ff, 0x4a040000, 0x002029ff, + 0x52040000, 0x004029ff, 0x5a040000, 0x006129ff, + 0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff, + 0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff, + 0x83040000, 0x000031ff, 0x8b040000, 0x002031ff, + 0x94040000, 0x004031ff, 0x9c040000, 0x006131ff, + 0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff, + 0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff, + 0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff, + 0xd5040000, 0x004039ff, 0xde040000, 0x006139ff, + 0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff, + 0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff, + 0x00080000, 0x000041ff, 0x08080000, 0x002041ff, + 0x10080000, 0x004041ff, 0x18080000, 0x006141ff, + 0x20080000, 0x008141ff, 0x29080000, 0x00a141ff, + 0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff, + 0x41080000, 0x00004aff, 0x4a080000, 0x00204aff, + 0x52080000, 0x00404aff, 0x5a080000, 0x00614aff, + 0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff, + 0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff, + 0x83080000, 0x000052ff, 0x8b080000, 0x002052ff, + 0x94080000, 0x004052ff, 0x9c080000, 0x006152ff, + 0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff, + 0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff, + 0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff, + 0xd5080000, 0x00405aff, 0xde080000, 0x00615aff, + 0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff, + 0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff, + 0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff, + 0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff, + 0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff, + 0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff, + 0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff, + 0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff, + 0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff, + 0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff, + 0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff, + 0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff, + 0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff, + 0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff, + 0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff, + 0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff, + 0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff, + 0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff, + 0x00100000, 0x000083ff, 0x08100000, 0x002083ff, + 0x10100000, 0x004083ff, 0x18100000, 0x006183ff, + 0x20100000, 0x008183ff, 0x29100000, 0x00a183ff, + 0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff, + 0x41100000, 0x00008bff, 0x4a100000, 0x00208bff, + 0x52100000, 0x00408bff, 0x5a100000, 0x00618bff, + 0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff, + 0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff, + 0x83100000, 0x000094ff, 0x8b100000, 0x002094ff, + 0x94100000, 0x004094ff, 0x9c100000, 0x006194ff, + 0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff, + 0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff, + 0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff, + 0xd5100000, 0x00409cff, 0xde100000, 0x00619cff, + 0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff, + 0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff, + 0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff, + 0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff, + 0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff, + 0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff, + 0x41140000, 0x0000acff, 0x4a140000, 0x0020acff, + 0x52140000, 0x0040acff, 0x5a140000, 0x0061acff, + 0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff, + 0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff, + 0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff, + 0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff, + 0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff, + 0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff, + 0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff, + 0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff, + 0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff, + 0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff, + 0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff, + 0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff, + 0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff, + 0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff, + 0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff, + 0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff, + 0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff, + 0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff, + 0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff, + 0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff, + 0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff, + 0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff, + 0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff, + 0xd5180000, 0x0040deff, 0xde180000, 0x0061deff, + 0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff, + 0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff, + 0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff, + 0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff, + 0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff, + 0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff, + 0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff, + 0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff, + 0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff, + 0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff, + 0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff, + 0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff, + 0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff, + 0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff, + 0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff, + 0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff, + 0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff, + 0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff +}; +static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_BGRA8888_LUT); +} + +/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ +#ifndef RGB888_RGB332 +#define RGB888_RGB332(dst, src) { \ + dst = (((src)&0x00E00000)>>16)| \ + (((src)&0x0000E000)>>11)| \ + (((src)&0x000000C0)>>6); \ +} +#endif +static void Blit_RGB888_index8_map(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int Pixel; + int width, height; + Uint32 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + , width); + src += srcskip; + dst += dstskip; + } +#else + while ( height-- ) { + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + case 2: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + case 1: + RGB888_RGB332(Pixel, *src); + *dst++ = map[Pixel]; + ++src; + } + src += srcskip; + dst += dstskip; + } +#endif /* USE_DUFFS_LOOP */ +} +static void BlitNto1(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + int srcbpp; + Uint32 Pixel; + int sR, sG, sB; + SDL_PixelFormat *srcfmt; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcfmt = info->src; + srcbpp = srcfmt->BytesPerPixel; + + if ( map == NULL ) { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = ((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ; + } + dst++; + src += srcbpp; + , width); +#else + for ( c=width; c; --c ) { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = ((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ; + } + dst++; + src += srcbpp; + } +#endif + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = map[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + , width); +#else + for ( c=width; c; --c ) { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = map[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } +} + +/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */ +static void Blit4to4MaskAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *src = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dst = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + + if (dstfmt->Amask) { + /* RGB->RGBA, SET_ALPHA */ + Uint32 mask = (srcfmt->alpha >> dstfmt->Aloss) << dstfmt->Ashift; + + while ( height-- ) { + DUFFS_LOOP( + { + *dst = *src | mask; + ++dst; + ++src; + }, + width); + src = (Uint32*)((Uint8*)src + srcskip); + dst = (Uint32*)((Uint8*)dst + dstskip); + } + } else { + /* RGBA->RGB, NO_ALPHA */ + Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; + + while ( height-- ) { + DUFFS_LOOP( + { + *dst = *src & mask; + ++dst; + ++src; + }, + width); + src = (Uint32*)((Uint8*)src + srcskip); + dst = (Uint32*)((Uint8*)dst + dstskip); + } + } +} + +static void BlitNtoN(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + int srcbpp = srcfmt->BytesPerPixel; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp = dstfmt->BytesPerPixel; + unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha); + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void BlitNtoNCopyAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + int srcbpp = srcfmt->BytesPerPixel; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp = dstfmt->BytesPerPixel; + int c; + + /* FIXME: should map alpha to [0..255] correctly! */ + while ( height-- ) { + for ( c=width; c; --c ) { + Uint32 Pixel; + unsigned sR, sG, sB, sA; + DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, + sR, sG, sB, sA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, sA); + dst += dstbpp; + src += srcbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitNto1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + const Uint8 *palmap = info->table; + Uint32 ckey = srcfmt->colorkey; + Uint32 rgbmask = ~srcfmt->Amask; + int srcbpp; + Uint32 Pixel; + unsigned sR, sG, sB; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + ckey &= rgbmask; + + if ( palmap == NULL ) { + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( (Pixel & rgbmask) != ckey ) { + /* Pack RGB into 8bit pixel */ + *dst = (Uint8)(((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0))); + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, + sR, sG, sB); + if ( (Pixel & rgbmask) != ckey ) { + /* Pack RGB into 8bit pixel */ + *dst = (Uint8)palmap[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } + } +} + +static void Blit2to2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint32 rgbmask = ~info->src->Amask; + + /* Set up some basic variables */ + srcskip /= 2; + dstskip /= 2; + ckey &= rgbmask; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( (*srcp & rgbmask) != ckey ) { + *dstp = *srcp; + } + dstp++; + srcp++; + }, + width); + srcp += srcskip; + dstp += dstskip; + } +} + +static void BlitNtoNKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0; + Uint32 rgbmask = ~srcfmt->Amask; + + /* Set up some basic variables */ + ckey &= rgbmask; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 Pixel; + unsigned sR; + unsigned sG; + unsigned sB; + RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel); + if ( (Pixel & rgbmask) != ckey ) { + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, alpha); + } + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + Uint32 rgbmask = ~srcfmt->Amask; + + Uint8 srcbpp; + Uint8 dstbpp; + Uint32 Pixel; + unsigned sR, sG, sB, sA; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + dstbpp = dstfmt->BytesPerPixel; + ckey &= rgbmask; + + /* FIXME: should map alpha to [0..255] correctly! */ + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, + sR, sG, sB, sA); + if ( (Pixel & rgbmask) != ckey ) { + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, sA); + } + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* Normal N to N optimized blitters */ +struct blit_table { + Uint32 srcR, srcG, srcB; + int dstbpp; + Uint32 dstR, dstG, dstB; + Uint32 blit_features; + void *aux_data; + SDL_loblit blitfunc; + enum { NO_ALPHA=1, SET_ALPHA=2, COPY_ALPHA=4 } alpha; +}; +static const struct blit_table normal_blit_1[] = { + /* Default for 8-bit RGB source, an invalid combination */ + { 0,0,0, 0, 0,0,0, 0, NULL, NULL }, +}; +static const struct blit_table normal_blit_2[] = { +#if SDL_HERMES_BLITTERS + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800, + 0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00, + 0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA }, +#elif SDL_ALTIVEC_BLITTERS + /* has-altivec */ + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000, + 2, NULL, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + { 0x00007C00,0x000003E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000, + 2, NULL, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, +#endif + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF, + 0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000, + 0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00, + 0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000, + 0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA }, + + /* Default for 16-bit RGB source, used if no other blitter matches */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table normal_blit_3[] = { + /* Default for 24-bit RGB source, never optimized */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table normal_blit_4[] = { +#if SDL_HERMES_BLITTERS + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + 1, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + 0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, + 1, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, + 0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + 1, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, + 1, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, + 0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF, + 1, ConvertMMXpII32_24RGB888, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF, + 0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000, + 0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000, + 0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00, + 0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000, + 0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA }, +#else +#if SDL_ALTIVEC_BLITTERS + /* has-altivec | dont-use-prefetch */ + { 0x00000000,0x00000000,0x00000000, 4, 0x00000000,0x00000000,0x00000000, + 6, NULL, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + /* has-altivec */ + { 0x00000000,0x00000000,0x00000000, 4, 0x00000000,0x00000000,0x00000000, + 2, NULL, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + /* has-altivec */ + { 0x00000000,0x00000000,0x00000000, 2, 0x0000F800,0x000007E0,0x0000001F, + 2, NULL, Blit_RGB888_RGB565Altivec, NO_ALPHA }, +#endif + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + 0, NULL, Blit_RGB888_RGB565, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, NULL, Blit_RGB888_RGB555, NO_ALPHA }, +#endif + /* Default for 32-bit RGB source, used if no other blitter matches */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table *normal_blit[] = { + normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4 +}; + +/* Mask matches table, or table entry is zero */ +#define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000)) + +SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index) +{ + struct private_swaccel *sdata; + SDL_PixelFormat *srcfmt; + SDL_PixelFormat *dstfmt; + const struct blit_table *table; + int which; + SDL_loblit blitfun; + + /* Set up data for choosing the blit */ + sdata = surface->map->sw_data; + srcfmt = surface->format; + dstfmt = surface->map->dst->format; + + if ( blit_index & 2 ) { + /* alpha or alpha+colorkey */ + return SDL_CalculateAlphaBlit(surface, blit_index); + } + + /* We don't support destinations less than 8-bits */ + if ( dstfmt->BitsPerPixel < 8 ) { + return(NULL); + } + + if(blit_index == 1) { + /* colorkey blit: Here we don't have too many options, mostly + because RLE is the preferred fast way to deal with this. + If a particular case turns out to be useful we'll add it. */ + + if(srcfmt->BytesPerPixel == 2 + && surface->map->identity) + return Blit2to2Key; + else if(dstfmt->BytesPerPixel == 1) + return BlitNto1Key; + else { +#if SDL_ALTIVEC_BLITTERS + if((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4) && SDL_HasAltiVec()) { + return Blit32to32KeyAltivec; + } else +#endif + + if(srcfmt->Amask && dstfmt->Amask) + return BlitNtoNKeyCopyAlpha; + else + return BlitNtoNKey; + } + } + + blitfun = NULL; + if ( dstfmt->BitsPerPixel == 8 ) { + /* We assume 8-bit destinations are palettized */ + if ( (srcfmt->BytesPerPixel == 4) && + (srcfmt->Rmask == 0x00FF0000) && + (srcfmt->Gmask == 0x0000FF00) && + (srcfmt->Bmask == 0x000000FF) ) { + if ( surface->map->table ) { + blitfun = Blit_RGB888_index8_map; + } else { +#if SDL_HERMES_BLITTERS + sdata->aux_data = ConvertX86p32_8RGB332; + blitfun = ConvertX86; +#else + blitfun = Blit_RGB888_index8; +#endif + } + } else { + blitfun = BlitNto1; + } + } else { + /* Now the meat, choose the blitter we want */ + int a_need = NO_ALPHA; + if(dstfmt->Amask) + a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA; + table = normal_blit[srcfmt->BytesPerPixel-1]; + for ( which=0; table[which].dstbpp; ++which ) { + if ( MASKOK(srcfmt->Rmask, table[which].srcR) && + MASKOK(srcfmt->Gmask, table[which].srcG) && + MASKOK(srcfmt->Bmask, table[which].srcB) && + MASKOK(dstfmt->Rmask, table[which].dstR) && + MASKOK(dstfmt->Gmask, table[which].dstG) && + MASKOK(dstfmt->Bmask, table[which].dstB) && + dstfmt->BytesPerPixel == table[which].dstbpp && + (a_need & table[which].alpha) == a_need && + ((table[which].blit_features & GetBlitFeatures()) == table[which].blit_features) ) + break; + } + sdata->aux_data = table[which].aux_data; + blitfun = table[which].blitfunc; + + if(blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */ + /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */ + if ( srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4 && + srcfmt->Rmask == dstfmt->Rmask && + srcfmt->Gmask == dstfmt->Gmask && + srcfmt->Bmask == dstfmt->Bmask ) { + blitfun = Blit4to4MaskAlpha; + } else if ( a_need == COPY_ALPHA ) { + blitfun = BlitNtoNCopyAlpha; + } + } + } + +#ifdef DEBUG_ASM +#if SDL_HERMES_BLITTERS + if ( blitfun == ConvertMMX ) + fprintf(stderr, "Using mmx blit\n"); + else + if ( blitfun == ConvertX86 ) + fprintf(stderr, "Using asm blit\n"); + else +#endif + if ( (blitfun == BlitNtoN) || (blitfun == BlitNto1) ) + fprintf(stderr, "Using C blit\n"); + else + fprintf(stderr, "Using optimized C blit\n"); +#endif /* DEBUG_ASM */ + + return(blitfun); +} diff --git a/apps/plugins/sdl/src/video/SDL_bmp.c b/apps/plugins/sdl/src/video/SDL_bmp.c new file mode 100644 index 0000000000..d56cfd83a3 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_bmp.c @@ -0,0 +1,549 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + Code to load and save surfaces in Windows BMP format. + + Why support BMP format? Well, it's a native format for Windows, and + most image processing programs can read and write it. It would be nice + to be able to have at least one image format that we can natively load + and save, and since PNG is so complex that it would bloat the library, + BMP is a good alternative. + + This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp. +*/ + +#include "SDL_video.h" +#include "SDL_endian.h" + +/* Compression encodings for BMP files */ +#ifndef BI_RGB +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 +#define BI_BITFIELDS 3 +#endif + + +SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) +{ + SDL_bool was_error; + long fp_offset = 0; + int bmpPitch; + int i, pad; + SDL_Surface *surface; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + SDL_Palette *palette; + Uint8 *bits; + Uint8 *top, *end; + SDL_bool topDown; + int ExpandBMP; + + /* The Win32 BMP file header (14 bytes) */ + char magic[2]; + Uint32 bfSize; + Uint16 bfReserved1; + Uint16 bfReserved2; + Uint32 bfOffBits; + + /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ + Uint32 biSize; + Sint32 biWidth; + Sint32 biHeight; + Uint16 biPlanes; + Uint16 biBitCount; + Uint32 biCompression; + Uint32 biSizeImage; + Sint32 biXPelsPerMeter; + Sint32 biYPelsPerMeter; + Uint32 biClrUsed; + Uint32 biClrImportant; + + /* Make sure we are passed a valid data source */ + surface = NULL; + was_error = SDL_FALSE; + if ( src == NULL ) { + was_error = SDL_TRUE; + goto done; + } + + /* Read in the BMP file header */ + fp_offset = SDL_RWtell(src); + SDL_ClearError(); + if ( SDL_RWread(src, magic, 1, 2) != 2 ) { + SDL_Error(SDL_EFREAD); + was_error = SDL_TRUE; + goto done; + } + if ( SDL_strncmp(magic, "BM", 2) != 0 ) { + SDL_SetError("File is not a Windows BMP file"); + was_error = SDL_TRUE; + goto done; + } + bfSize = SDL_ReadLE32(src); + bfReserved1 = SDL_ReadLE16(src); + bfReserved2 = SDL_ReadLE16(src); + bfOffBits = SDL_ReadLE32(src); + + /* Read the Win32 BITMAPINFOHEADER */ + biSize = SDL_ReadLE32(src); + if ( biSize == 12 ) { + biWidth = (Uint32)SDL_ReadLE16(src); + biHeight = (Uint32)SDL_ReadLE16(src); + biPlanes = SDL_ReadLE16(src); + biBitCount = SDL_ReadLE16(src); + biCompression = BI_RGB; + biSizeImage = 0; + biXPelsPerMeter = 0; + biYPelsPerMeter = 0; + biClrUsed = 0; + biClrImportant = 0; + } else { + biWidth = SDL_ReadLE32(src); + biHeight = SDL_ReadLE32(src); + biPlanes = SDL_ReadLE16(src); + biBitCount = SDL_ReadLE16(src); + biCompression = SDL_ReadLE32(src); + biSizeImage = SDL_ReadLE32(src); + biXPelsPerMeter = SDL_ReadLE32(src); + biYPelsPerMeter = SDL_ReadLE32(src); + biClrUsed = SDL_ReadLE32(src); + biClrImportant = SDL_ReadLE32(src); + } + + /* stop some compiler warnings. */ + (void) bfSize; + (void) bfReserved1; + (void) bfReserved2; + (void) biPlanes; + (void) biSizeImage; + (void) biXPelsPerMeter; + (void) biYPelsPerMeter; + (void) biClrImportant; + + if (biHeight < 0) { + topDown = SDL_TRUE; + biHeight = -biHeight; + } else { + topDown = SDL_FALSE; + } + + /* Check for read error */ + if ( SDL_strcmp(SDL_GetError(), "") != 0 ) { + was_error = SDL_TRUE; + goto done; + } + + /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ + switch (biBitCount) { + case 1: + case 4: + ExpandBMP = biBitCount; + biBitCount = 8; + break; + default: + ExpandBMP = 0; + break; + } + + /* We don't support any BMP compression right now */ + Rmask = Gmask = Bmask = 0; + switch (biCompression) { + case BI_RGB: + /* If there are no masks, use the defaults */ + if ( bfOffBits == (14+biSize) ) { + /* Default values for the BMP format */ + switch (biBitCount) { + case 15: + case 16: + Rmask = 0x7C00; + Gmask = 0x03E0; + Bmask = 0x001F; + break; + case 24: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + break; +#endif + case 32: + Rmask = 0x00FF0000; + Gmask = 0x0000FF00; + Bmask = 0x000000FF; + break; + default: + break; + } + break; + } + /* Fall through -- read the RGB masks */ + + case BI_BITFIELDS: + switch (biBitCount) { + case 15: + case 16: + case 32: + Rmask = SDL_ReadLE32(src); + Gmask = SDL_ReadLE32(src); + Bmask = SDL_ReadLE32(src); + break; + default: + break; + } + break; + default: + SDL_SetError("Compressed BMP files not supported"); + was_error = SDL_TRUE; + goto done; + } + + /* Create a compatible surface, note that the colors are RGB ordered */ + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); + if ( surface == NULL ) { + was_error = SDL_TRUE; + goto done; + } + + /* Load the palette, if any */ + palette = (surface->format)->palette; + if ( palette ) { + if ( biClrUsed == 0 ) { + biClrUsed = 1 << biBitCount; + } + if ( biSize == 12 ) { + for ( i = 0; i < (int)biClrUsed; ++i ) { + SDL_RWread(src, &palette->colors[i].b, 1, 1); + SDL_RWread(src, &palette->colors[i].g, 1, 1); + SDL_RWread(src, &palette->colors[i].r, 1, 1); + palette->colors[i].unused = 0; + } + } else { + for ( i = 0; i < (int)biClrUsed; ++i ) { + SDL_RWread(src, &palette->colors[i].b, 1, 1); + SDL_RWread(src, &palette->colors[i].g, 1, 1); + SDL_RWread(src, &palette->colors[i].r, 1, 1); + SDL_RWread(src, &palette->colors[i].unused, 1, 1); + } + } + palette->ncolors = biClrUsed; + } + + /* Read the surface pixels. Note that the bmp image is upside down */ + if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) { + SDL_Error(SDL_EFSEEK); + was_error = SDL_TRUE; + goto done; + } + top = (Uint8 *)surface->pixels; + end = (Uint8 *)surface->pixels+(surface->h*surface->pitch); + switch (ExpandBMP) { + case 1: + bmpPitch = (biWidth + 7) >> 3; + pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); + break; + case 4: + bmpPitch = (biWidth + 1) >> 1; + pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); + break; + default: + pad = ((surface->pitch%4) ? + (4-(surface->pitch%4)) : 0); + break; + } + if ( topDown ) { + bits = top; + } else { + bits = end - surface->pitch; + } + while ( bits >= top && bits < end ) { + switch (ExpandBMP) { + case 1: + case 4: { + Uint8 pixel = 0; + int shift = (8-ExpandBMP); + for ( i=0; iw; ++i ) { + if ( i%(8/ExpandBMP) == 0 ) { + if ( !SDL_RWread(src, &pixel, 1, 1) ) { + SDL_SetError( + "Error reading from BMP"); + was_error = SDL_TRUE; + goto done; + } + } + *(bits+i) = (pixel>>shift); + pixel <<= ExpandBMP; + } } + break; + + default: + if ( SDL_RWread(src, bits, 1, surface->pitch) + != surface->pitch ) { + SDL_Error(SDL_EFREAD); + was_error = SDL_TRUE; + goto done; + } +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + /* Byte-swap the pixels if needed. Note that the 24bpp + case has already been taken care of above. */ + switch(biBitCount) { + case 15: + case 16: { + Uint16 *pix = (Uint16 *)bits; + for(i = 0; i < surface->w; i++) + pix[i] = SDL_Swap16(pix[i]); + break; + } + + case 32: { + Uint32 *pix = (Uint32 *)bits; + for(i = 0; i < surface->w; i++) + pix[i] = SDL_Swap32(pix[i]); + break; + } + } +#endif + break; + } + /* Skip padding bytes, ugh */ + if ( pad ) { + Uint8 padbyte; + for ( i=0; ipitch; + } else { + bits -= surface->pitch; + } + } +done: + if ( was_error ) { + if ( src ) { + SDL_RWseek(src, fp_offset, RW_SEEK_SET); + } + if ( surface ) { + SDL_FreeSurface(surface); + } + surface = NULL; + } + if ( freesrc && src ) { + SDL_RWclose(src); + } + return(surface); +} + +int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst) +{ + long fp_offset; + int i, pad; + SDL_Surface *surface; + Uint8 *bits; + + /* The Win32 BMP file header (14 bytes) */ + char magic[2] = { 'B', 'M' }; + Uint32 bfSize; + Uint16 bfReserved1; + Uint16 bfReserved2; + Uint32 bfOffBits; + + /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ + Uint32 biSize; + Sint32 biWidth; + Sint32 biHeight; + Uint16 biPlanes; + Uint16 biBitCount; + Uint32 biCompression; + Uint32 biSizeImage; + Sint32 biXPelsPerMeter; + Sint32 biYPelsPerMeter; + Uint32 biClrUsed; + Uint32 biClrImportant; + + /* Make sure we have somewhere to save */ + surface = NULL; + if ( dst ) { + if ( saveme->format->palette ) { + if ( saveme->format->BitsPerPixel == 8 ) { + surface = saveme; + } else { + SDL_SetError("%d bpp BMP files not supported", + saveme->format->BitsPerPixel); + } + } + else if ( (saveme->format->BitsPerPixel == 24) && +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + (saveme->format->Rmask == 0x00FF0000) && + (saveme->format->Gmask == 0x0000FF00) && + (saveme->format->Bmask == 0x000000FF) +#else + (saveme->format->Rmask == 0x000000FF) && + (saveme->format->Gmask == 0x0000FF00) && + (saveme->format->Bmask == 0x00FF0000) +#endif + ) { + surface = saveme; + } else { + SDL_Rect bounds; + + /* Convert to 24 bits per pixel */ + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + saveme->w, saveme->h, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x00FF0000, 0x0000FF00, 0x000000FF, +#else + 0x000000FF, 0x0000FF00, 0x00FF0000, +#endif + 0); + if ( surface != NULL ) { + bounds.x = 0; + bounds.y = 0; + bounds.w = saveme->w; + bounds.h = saveme->h; + if ( SDL_LowerBlit(saveme, &bounds, surface, + &bounds) < 0 ) { + SDL_FreeSurface(surface); + SDL_SetError( + "Couldn't convert image to 24 bpp"); + surface = NULL; + } + } + } + } + + if ( surface && (SDL_LockSurface(surface) == 0) ) { + const int bw = surface->w*surface->format->BytesPerPixel; + + /* Set the BMP file header values */ + bfSize = 0; /* We'll write this when we're done */ + bfReserved1 = 0; + bfReserved2 = 0; + bfOffBits = 0; /* We'll write this when we're done */ + + /* Write the BMP file header values */ + fp_offset = SDL_RWtell(dst); + SDL_ClearError(); + SDL_RWwrite(dst, magic, 2, 1); + SDL_WriteLE32(dst, bfSize); + SDL_WriteLE16(dst, bfReserved1); + SDL_WriteLE16(dst, bfReserved2); + SDL_WriteLE32(dst, bfOffBits); + + /* Set the BMP info values */ + biSize = 40; + biWidth = surface->w; + biHeight = surface->h; + biPlanes = 1; + biBitCount = surface->format->BitsPerPixel; + biCompression = BI_RGB; + biSizeImage = surface->h*surface->pitch; + biXPelsPerMeter = 0; + biYPelsPerMeter = 0; + if ( surface->format->palette ) { + biClrUsed = surface->format->palette->ncolors; + } else { + biClrUsed = 0; + } + biClrImportant = 0; + + /* Write the BMP info values */ + SDL_WriteLE32(dst, biSize); + SDL_WriteLE32(dst, biWidth); + SDL_WriteLE32(dst, biHeight); + SDL_WriteLE16(dst, biPlanes); + SDL_WriteLE16(dst, biBitCount); + SDL_WriteLE32(dst, biCompression); + SDL_WriteLE32(dst, biSizeImage); + SDL_WriteLE32(dst, biXPelsPerMeter); + SDL_WriteLE32(dst, biYPelsPerMeter); + SDL_WriteLE32(dst, biClrUsed); + SDL_WriteLE32(dst, biClrImportant); + + /* Write the palette (in BGR color order) */ + if ( surface->format->palette ) { + SDL_Color *colors; + int ncolors; + + colors = surface->format->palette->colors; + ncolors = surface->format->palette->ncolors; + for ( i=0; ipixels+(surface->h*surface->pitch); + pad = ((bw%4) ? (4-(bw%4)) : 0); + while ( bits > (Uint8 *)surface->pixels ) { + bits -= surface->pitch; + if ( SDL_RWwrite(dst, bits, 1, bw) != bw) { + SDL_Error(SDL_EFWRITE); + break; + } + if ( pad ) { + const Uint8 padbyte = 0; + for ( i=0; i= w) || (hot_y >= h) ) { + SDL_SetError("Cursor hot spot doesn't lie within cursor"); + return(NULL); + } + + /* Allocate memory for the cursor */ + cursor = (SDL_Cursor *)SDL_malloc(sizeof *cursor); + if ( cursor == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + savelen = (w*4)*h; + cursor->area.x = 0; + cursor->area.y = 0; + cursor->area.w = w; + cursor->area.h = h; + cursor->hot_x = hot_x; + cursor->hot_y = hot_y; + cursor->data = (Uint8 *)SDL_malloc((w/8)*h*2); + cursor->mask = cursor->data+((w/8)*h); + cursor->save[0] = (Uint8 *)SDL_malloc(savelen*2); + cursor->save[1] = cursor->save[0] + savelen; + cursor->wm_cursor = NULL; + if ( ! cursor->data || ! cursor->save[0] ) { + SDL_FreeCursor(cursor); + SDL_OutOfMemory(); + return(NULL); + } + for ( i=((w/8)*h)-1; i>=0; --i ) { + cursor->data[i] = data[i]; + cursor->mask[i] = mask[i] | data[i]; + } + SDL_memset(cursor->save[0], 0, savelen*2); + + /* If the window manager gives us a good cursor, we're done! */ + if ( video->CreateWMCursor ) { + cursor->wm_cursor = video->CreateWMCursor(video, data, mask, + w, h, hot_x, hot_y); + } else { + cursor->wm_cursor = NULL; + } + return(cursor); +} + +/* SDL_SetCursor(NULL) can be used to force the cursor redraw, + if this is desired for any reason. This is used when setting + the video mode and when the SDL window gains the mouse focus. + */ +void SDL_SetCursor (SDL_Cursor *cursor) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Make sure that the video subsystem has been initialized */ + if ( ! video ) { + return; + } + /* Prevent the event thread from moving the mouse */ + SDL_LockCursor(); + + /* Set the new cursor */ + if ( cursor && (cursor != SDL_cursor) ) { + /* Erase the current mouse position */ + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + SDL_EraseCursor(SDL_VideoSurface); + } else if ( video->MoveWMCursor ) { + /* If the video driver is moving the cursor directly, + it needs to hide the old cursor before (possibly) + showing the new one. (But don't erase NULL cursor) + */ + if ( SDL_cursor && video->ShowWMCursor ) { + video->ShowWMCursor(this, NULL); + } + } + SDL_cursor = cursor; + } + + /* Draw the new mouse cursor */ + if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) { + /* Use window manager cursor if possible */ + int show_wm_cursor = 0; + if ( SDL_cursor->wm_cursor && video->ShowWMCursor ) { + show_wm_cursor = video->ShowWMCursor(this, SDL_cursor->wm_cursor); + } + if ( show_wm_cursor ) { + SDL_cursorstate &= ~CURSOR_USINGSW; + } else { + SDL_cursorstate |= CURSOR_USINGSW; + if ( video->ShowWMCursor ) { + video->ShowWMCursor(this, NULL); + } + { int x, y; + SDL_GetMouseState(&x, &y); + SDL_cursor->area.x = (x - SDL_cursor->hot_x); + SDL_cursor->area.y = (y - SDL_cursor->hot_y); + } + SDL_DrawCursor(SDL_VideoSurface); + } + + } else { + /* Erase window manager mouse (cursor not visible) */ + if ( SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW) ) { + SDL_EraseCursor(SDL_VideoSurface); + } else { + if ( video ) { + if ( video->ShowWMCursor ) { + video->ShowWMCursor(this, NULL); + } + } + } + } + SDL_UnlockCursor(); +} + +SDL_Cursor * SDL_GetCursor (void) +{ + return(SDL_cursor); +} + +void SDL_FreeCursor (SDL_Cursor *cursor) +{ + if ( cursor ) { + if ( cursor == SDL_cursor ) { + SDL_SetCursor(SDL_defcursor); + } + if ( cursor != SDL_defcursor ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( cursor->data ) { + SDL_free(cursor->data); + } + if ( cursor->save[0] ) { + SDL_free(cursor->save[0]); + } + if ( video && cursor->wm_cursor ) { + if ( video->FreeWMCursor ) { + video->FreeWMCursor(this, cursor->wm_cursor); + } + } + SDL_free(cursor); + } + } +} + +int SDL_ShowCursor (int toggle) +{ + int showing; + + showing = (SDL_cursorstate & CURSOR_VISIBLE); + if ( toggle >= 0 ) { + SDL_LockCursor(); + if ( toggle ) { + SDL_cursorstate |= CURSOR_VISIBLE; + } else { + SDL_cursorstate &= ~CURSOR_VISIBLE; + } + SDL_UnlockCursor(); + if ( (SDL_cursorstate & CURSOR_VISIBLE) != showing ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + SDL_SetCursor(NULL); + if ( video && video->CheckMouseMode ) { + video->CheckMouseMode(this); + } + } + } else { + /* Query current state */ ; + } + return(showing ? 1 : 0); +} + +void SDL_WarpMouse (Uint16 x, Uint16 y) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( !video || !SDL_PublicSurface ) { + SDL_SetError("A video mode must be set before warping mouse"); + return; + } + + /* If we have an offset video mode, offset the mouse coordinates */ + if (this->screen->pitch == 0) { + x += this->screen->offset / this->screen->format->BytesPerPixel; + y += this->screen->offset; + } else { + x += (this->screen->offset % this->screen->pitch) / + this->screen->format->BytesPerPixel; + y += (this->screen->offset / this->screen->pitch); + } + + /* This generates a mouse motion event */ + if ( video->WarpWMCursor ) { + video->WarpWMCursor(this, x, y); + } else { + SDL_PrivateMouseMotion(0, 0, x, y); + } +} + +void SDL_MoveCursor(int x, int y) +{ + SDL_VideoDevice *video = current_video; + + /* Erase and update the current mouse position */ + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + /* Erase and redraw mouse cursor in new position */ + SDL_LockCursor(); + SDL_EraseCursor(SDL_VideoSurface); + SDL_cursor->area.x = (x - SDL_cursor->hot_x); + SDL_cursor->area.y = (y - SDL_cursor->hot_y); + SDL_DrawCursor(SDL_VideoSurface); + SDL_UnlockCursor(); + } else if ( video->MoveWMCursor ) { + video->MoveWMCursor(video, x, y); + } +} + +/* Keep track of the current cursor colors */ +static int palette_changed = 1; +static Uint8 pixels8[2]; + +void SDL_CursorPaletteChanged(void) +{ + palette_changed = 1; +} + +void SDL_MouseRect(SDL_Rect *area) +{ + int clip_diff; + + *area = SDL_cursor->area; + if ( area->x < 0 ) { + area->w += area->x; + area->x = 0; + } + if ( area->y < 0 ) { + area->h += area->y; + area->y = 0; + } + clip_diff = (area->x+area->w)-SDL_VideoSurface->w; + if ( clip_diff > 0 ) { + area->w = area->w < clip_diff ? 0 : area->w-clip_diff; + } + clip_diff = (area->y+area->h)-SDL_VideoSurface->h; + if ( clip_diff > 0 ) { + area->h = area->h < clip_diff ? 0 : area->h-clip_diff; + } +} + +static void SDL_DrawCursorFast(SDL_Surface *screen, SDL_Rect *area) +{ + const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; + int i, w, h; + Uint8 *data, datab; + Uint8 *mask, maskb; + + data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; + mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; + switch (screen->format->BytesPerPixel) { + + case 1: { + Uint8 *dst; + int dstskip; + + if ( palette_changed ) { + pixels8[0] = (Uint8)SDL_MapRGB(screen->format, 255, 255, 255); + pixels8[1] = (Uint8)SDL_MapRGB(screen->format, 0, 0, 0); + palette_changed = 0; + } + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x; + dstskip = screen->pitch-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = pixels8[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + + case 2: { + Uint16 *dst; + int dstskip; + + dst = (Uint16 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch/2 + + SDL_cursor->area.x; + dstskip = (screen->pitch/2)-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = (Uint16)pixels[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + + case 3: { + Uint8 *dst; + int dstskip; + + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x*3; + dstskip = screen->pitch-area->w*3; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + SDL_memset(dst,pixels[datab>>7],3); + } + maskb <<= 1; + datab <<= 1; + dst += 3; + } + } + dst += dstskip; + } + } + break; + + case 4: { + Uint32 *dst; + int dstskip; + + dst = (Uint32 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch/4 + + SDL_cursor->area.x; + dstskip = (screen->pitch/4)-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = pixels[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + } +} + +static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area) +{ + const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; + int h; + int x, minx, maxx; + Uint8 *data, datab = 0; + Uint8 *mask, maskb = 0; + Uint8 *dst; + int dstbpp, dstskip; + + data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; + mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; + dstbpp = screen->format->BytesPerPixel; + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x*dstbpp; + dstskip = screen->pitch-SDL_cursor->area.w*dstbpp; + + minx = area->x; + maxx = area->x+area->w; + if ( screen->format->BytesPerPixel == 1 ) { + if ( palette_changed ) { + pixels8[0] = (Uint8)SDL_MapRGB(screen->format, 255, 255, 255); + pixels8[1] = (Uint8)SDL_MapRGB(screen->format, 0, 0, 0); + palette_changed = 0; + } + for ( h=area->h; h; h-- ) { + for ( x=0; xarea.w; ++x ) { + if ( (x%8) == 0 ) { + maskb = *mask++; + datab = *data++; + } + if ( (x >= minx) && (x < maxx) ) { + if ( maskb & 0x80 ) { + SDL_memset(dst, pixels8[datab>>7], dstbpp); + } + } + maskb <<= 1; + datab <<= 1; + dst += dstbpp; + } + dst += dstskip; + } + } else { + for ( h=area->h; h; h-- ) { + for ( x=0; xarea.w; ++x ) { + if ( (x%8) == 0 ) { + maskb = *mask++; + datab = *data++; + } + if ( (x >= minx) && (x < maxx) ) { + if ( maskb & 0x80 ) { + SDL_memset(dst, pixels[datab>>7], dstbpp); + } + } + maskb <<= 1; + datab <<= 1; + dst += dstbpp; + } + dst += dstskip; + } + } +} + +/* This handles the ugly work of converting the saved cursor background from + the pixel format of the shadow surface to that of the video surface. + This is only necessary when blitting from a shadow surface of a different + pixel format than the video surface, and using a software rendered cursor. +*/ +static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h) +{ + SDL_BlitInfo info; + SDL_loblit RunBlit; + + /* Make sure we can steal the blit mapping */ + if ( screen->map->dst != SDL_VideoSurface ) { + return; + } + + /* Set up the blit information */ + info.s_pixels = SDL_cursor->save[1]; + info.s_width = w; + info.s_height = h; + info.s_skip = 0; + info.d_pixels = SDL_cursor->save[0]; + info.d_width = w; + info.d_height = h; + info.d_skip = 0; + info.aux_data = screen->map->sw_data->aux_data; + info.src = screen->format; + info.table = screen->map->table; + info.dst = SDL_VideoSurface->format; + RunBlit = screen->map->sw_data->blit; + + /* Run the actual software blit */ + RunBlit(&info); +} + +void SDL_DrawCursorNoLock(SDL_Surface *screen) +{ + SDL_Rect area; + + /* Get the mouse rectangle, clipped to the screen */ + SDL_MouseRect(&area); + if ( (area.w == 0) || (area.h == 0) ) { + return; + } + + /* Copy mouse background */ + { int w, h, screenbpp; + Uint8 *src, *dst; + + /* Set up the copy pointers */ + screenbpp = screen->format->BytesPerPixel; + if ( (screen == SDL_VideoSurface) || + FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { + dst = SDL_cursor->save[0]; + } else { + dst = SDL_cursor->save[1]; + } + src = (Uint8 *)screen->pixels + area.y * screen->pitch + + area.x * screenbpp; + + /* Perform the copy */ + w = area.w*screenbpp; + h = area.h; + while ( h-- ) { + SDL_memcpy(dst, src, w); + dst += w; + src += screen->pitch; + } + } + + /* Draw the mouse cursor */ + area.x -= SDL_cursor->area.x; + area.y -= SDL_cursor->area.y; + if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) { + SDL_DrawCursorFast(screen, &area); + } else { + SDL_DrawCursorSlow(screen, &area); + } +} + +void SDL_DrawCursor(SDL_Surface *screen) +{ + /* Lock the screen if necessary */ + if ( screen == NULL ) { + return; + } + if ( SDL_MUSTLOCK(screen) ) { + if ( SDL_LockSurface(screen) < 0 ) { + return; + } + } + + SDL_DrawCursorNoLock(screen); + + /* Unlock the screen and update if necessary */ + if ( SDL_MUSTLOCK(screen) ) { + SDL_UnlockSurface(screen); + } + if ( (screen == SDL_VideoSurface) && + ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect area; + + SDL_MouseRect(&area); + + /* This can be called before a video mode is set */ + if ( video->UpdateRects ) { + video->UpdateRects(this, 1, &area); + } + } +} + +void SDL_EraseCursorNoLock(SDL_Surface *screen) +{ + SDL_Rect area; + + /* Get the mouse rectangle, clipped to the screen */ + SDL_MouseRect(&area); + if ( (area.w == 0) || (area.h == 0) ) { + return; + } + + /* Copy mouse background */ + { int w, h, screenbpp; + Uint8 *src, *dst; + + /* Set up the copy pointers */ + screenbpp = screen->format->BytesPerPixel; + if ( (screen == SDL_VideoSurface) || + FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { + src = SDL_cursor->save[0]; + } else { + src = SDL_cursor->save[1]; + } + dst = (Uint8 *)screen->pixels + area.y * screen->pitch + + area.x * screenbpp; + + /* Perform the copy */ + w = area.w*screenbpp; + h = area.h; + while ( h-- ) { + SDL_memcpy(dst, src, w); + src += w; + dst += screen->pitch; + } + + /* Perform pixel conversion on cursor background */ + if ( src > SDL_cursor->save[1] ) { + SDL_ConvertCursorSave(screen, area.w, area.h); + } + } +} + +void SDL_EraseCursor(SDL_Surface *screen) +{ + /* Lock the screen if necessary */ + if ( screen == NULL ) { + return; + } + if ( SDL_MUSTLOCK(screen) ) { + if ( SDL_LockSurface(screen) < 0 ) { + return; + } + } + + SDL_EraseCursorNoLock(screen); + + /* Unlock the screen and update if necessary */ + if ( SDL_MUSTLOCK(screen) ) { + SDL_UnlockSurface(screen); + } + if ( (screen == SDL_VideoSurface) && + ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect area; + + SDL_MouseRect(&area); + if ( video->UpdateRects ) { + video->UpdateRects(this, 1, &area); + } + } +} + +/* Reset the cursor on video mode change + FIXME: Keep track of all cursors, and reset them all. + */ +void SDL_ResetCursor(void) +{ + int savelen; + + if ( SDL_cursor ) { + savelen = SDL_cursor->area.w*4*SDL_cursor->area.h; + SDL_cursor->area.x = 0; + SDL_cursor->area.y = 0; + SDL_memset(SDL_cursor->save[0], 0, savelen); + } +} diff --git a/apps/plugins/sdl/src/video/SDL_cursor_c.h b/apps/plugins/sdl/src/video/SDL_cursor_c.h new file mode 100644 index 0000000000..8be8df912c --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_cursor_c.h @@ -0,0 +1,73 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Useful variables and functions from SDL_cursor.c */ +#include "SDL_mouse.h" + +extern int SDL_CursorInit(Uint32 flags); +extern void SDL_CursorPaletteChanged(void); +extern void SDL_DrawCursor(SDL_Surface *screen); +extern void SDL_DrawCursorNoLock(SDL_Surface *screen); +extern void SDL_EraseCursor(SDL_Surface *screen); +extern void SDL_EraseCursorNoLock(SDL_Surface *screen); +extern void SDL_UpdateCursor(SDL_Surface *screen); +extern void SDL_ResetCursor(void); +extern void SDL_MoveCursor(int x, int y); +extern void SDL_CursorQuit(void); + +#define INLINE_MOUSELOCK +#ifdef INLINE_MOUSELOCK +/* Inline (macro) versions of the mouse lock functions */ +#include "SDL_mutex.h" + +extern SDL_mutex *SDL_cursorlock; + +#define SDL_LockCursor() \ + do { \ + if ( SDL_cursorlock ) { \ + SDL_mutexP(SDL_cursorlock); \ + } \ + } while ( 0 ) +#define SDL_UnlockCursor() \ + do { \ + if ( SDL_cursorlock ) { \ + SDL_mutexV(SDL_cursorlock); \ + } \ + } while ( 0 ) +#else +extern void SDL_LockCursor(void); +extern void SDL_UnlockCursor(void); +#endif /* INLINE_MOUSELOCK */ + +/* Only for low-level mouse cursor drawing */ +extern SDL_Cursor *SDL_cursor; +extern void SDL_MouseRect(SDL_Rect *area); + +/* State definitions for the SDL cursor */ +#define CURSOR_VISIBLE 0x01 +#define CURSOR_USINGSW 0x10 +#define SHOULD_DRAWCURSOR(X) \ + (((X)&(CURSOR_VISIBLE|CURSOR_USINGSW)) == \ + (CURSOR_VISIBLE|CURSOR_USINGSW)) + +extern volatile int SDL_cursorstate; diff --git a/apps/plugins/sdl/src/video/SDL_gamma.c b/apps/plugins/sdl/src/video/SDL_gamma.c new file mode 100644 index 0000000000..4fd037019f --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_gamma.c @@ -0,0 +1,233 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Gamma correction support */ + +#ifdef HAVE_MATH_H +#include /* Used for calculating gamma ramps */ +#else +/* Math routines from uClibc: http://www.uclibc.org */ +#include "math_private.h" +#include "e_sqrt.h" +#include "e_pow.h" +#include "e_log.h" +#define pow(x, y) __ieee754_pow(x, y) +#define log(x) __ieee754_log(x) +#endif + +#include "SDL_sysvideo.h" + + +static void CalculateGammaRamp(float gamma, Uint16 *ramp) +{ + int i; + + /* 0.0 gamma is all black */ + if ( gamma <= 0.0f ) { + for ( i=0; i<256; ++i ) { + ramp[i] = 0; + } + return; + } else + /* 1.0 gamma is identity */ + if ( gamma == 1.0f ) { + for ( i=0; i<256; ++i ) { + ramp[i] = (i << 8) | i; + } + return; + } else + /* Calculate a real gamma ramp */ + { int value; + gamma = 1.0f / gamma; + for ( i=0; i<256; ++i ) { + value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); + if ( value > 65535 ) { + value = 65535; + } + ramp[i] = (Uint16)value; + } + } +} +static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) +{ + /* The following is adapted from a post by Garrett Bass on OpenGL + Gamedev list, March 4, 2000. + */ + float sum = 0.0f; + int i, count = 0; + + *gamma = 1.0; + for ( i = 1; i < 256; ++i ) { + if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { + double B = (double)i / 256.0; + double A = ramp[i] / 65535.0; + sum += (float) ( log(A) / log(B) ); + count++; + } + } + if ( count && sum > 0.0f ) { + *gamma = 1.0f / (sum / count); + } +} + +int SDL_SetGamma(float red, float green, float blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + succeeded = -1; + /* Prefer using SetGammaRamp(), as it's more flexible */ + { + Uint16 ramp[3][256]; + + CalculateGammaRamp(red, ramp[0]); + CalculateGammaRamp(green, ramp[1]); + CalculateGammaRamp(blue, ramp[2]); + succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); + } + if ( (succeeded < 0) && video->SetGamma ) { + SDL_ClearError(); + succeeded = video->SetGamma(this, red, green, blue); + } + return succeeded; +} + +/* Calculating the gamma by integrating the gamma ramps isn't exact, + so this function isn't officially supported. +*/ +int SDL_GetGamma(float *red, float *green, float *blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + succeeded = -1; + /* Prefer using GetGammaRamp(), as it's more flexible */ + { + Uint16 ramp[3][256]; + + succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); + if ( succeeded >= 0 ) { + CalculateGammaFromRamp(red, ramp[0]); + CalculateGammaFromRamp(green, ramp[1]); + CalculateGammaFromRamp(blue, ramp[2]); + } + } + if ( (succeeded < 0) && video->GetGamma ) { + SDL_ClearError(); + succeeded = video->GetGamma(this, red, green, blue); + } + return succeeded; +} + +int SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Surface *screen = SDL_PublicSurface; + + /* Verify the screen parameter */ + if ( !screen ) { + SDL_SetError("No video mode has been set"); + return -1; + } + + /* Lazily allocate the gamma tables */ + if ( ! video->gamma ) { + SDL_GetGammaRamp(0, 0, 0); + } + + /* Fill the gamma table with the new values */ + if ( red ) { + SDL_memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); + } + if ( green ) { + SDL_memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); + } + if ( blue ) { + SDL_memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); + } + + /* Gamma correction always possible on split palettes */ + if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { + SDL_Palette *pal = screen->format->palette; + + /* If physical palette has been set independently, use it */ + if(video->physpal) + pal = video->physpal; + + SDL_SetPalette(screen, SDL_PHYSPAL, + pal->colors, 0, pal->ncolors); + return 0; + } + + /* Try to set the gamma ramp in the driver */ + succeeded = -1; + if ( video->SetGammaRamp ) { + succeeded = video->SetGammaRamp(this, video->gamma); + } else { + SDL_SetError("Gamma ramp manipulation not supported"); + } + return succeeded; +} + +int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Lazily allocate the gamma table */ + if ( ! video->gamma ) { + video->gamma = SDL_malloc(3*256*sizeof(*video->gamma)); + if ( ! video->gamma ) { + SDL_OutOfMemory(); + return -1; + } + if ( video->GetGammaRamp ) { + /* Get the real hardware gamma */ + video->GetGammaRamp(this, video->gamma); + } else { + /* Assume an identity gamma */ + int i; + for ( i=0; i<256; ++i ) { + video->gamma[0*256+i] = (i << 8) | i; + video->gamma[1*256+i] = (i << 8) | i; + video->gamma[2*256+i] = (i << 8) | i; + } + } + } + + /* Just copy from our internal table */ + if ( red ) { + SDL_memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); + } + if ( green ) { + SDL_memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); + } + if ( blue ) { + SDL_memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); + } + return 0; +} diff --git a/apps/plugins/sdl/src/video/SDL_glfuncs.h b/apps/plugins/sdl/src/video/SDL_glfuncs.h new file mode 100644 index 0000000000..fb2d964879 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_glfuncs.h @@ -0,0 +1,341 @@ +/* list of OpenGL functions sorted alphabetically + If you need to use a GL function from the SDL video subsystem, + change it's entry from SDL_PROC_UNUSED to SDL_PROC and rebuild. +*/ +#define SDL_PROC_UNUSED(ret,func,params) +SDL_PROC_UNUSED(void,glAccum,(GLenum,GLfloat)) +SDL_PROC_UNUSED(void,glAlphaFunc,(GLenum,GLclampf)) +SDL_PROC_UNUSED(GLboolean,glAreTexturesResident,(GLsizei,const GLuint*,GLboolean*)) +SDL_PROC_UNUSED(void,glArrayElement,(GLint)) +SDL_PROC(void,glBegin,(GLenum)) +SDL_PROC(void,glBindTexture,(GLenum,GLuint)) +SDL_PROC_UNUSED(void,glBitmap,(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*)) +SDL_PROC(void,glBlendFunc,(GLenum,GLenum)) +SDL_PROC_UNUSED(void,glCallList,(GLuint)) +SDL_PROC_UNUSED(void,glCallLists,(GLsizei,GLenum,const GLvoid*)) +SDL_PROC_UNUSED(void,glClear,(GLbitfield)) +SDL_PROC_UNUSED(void,glClearAccum,(GLfloat,GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf)) +SDL_PROC_UNUSED(void,glClearDepth,(GLclampd)) +SDL_PROC_UNUSED(void,glClearIndex,(GLfloat)) +SDL_PROC_UNUSED(void,glClearStencil,(GLint)) +SDL_PROC_UNUSED(void,glClipPlane,(GLenum,const GLdouble*)) +SDL_PROC_UNUSED(void,glColor3b,(GLbyte,GLbyte,GLbyte)) +SDL_PROC_UNUSED(void,glColor3bv,(const GLbyte*)) +SDL_PROC_UNUSED(void,glColor3d,(GLdouble,GLdouble,GLdouble)) +SDL_PROC_UNUSED(void,glColor3dv,(const GLdouble*)) +SDL_PROC_UNUSED(void,glColor3f,(GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glColor3fv,(const GLfloat*)) +SDL_PROC_UNUSED(void,glColor3i,(GLint,GLint,GLint)) +SDL_PROC_UNUSED(void,glColor3iv,(const GLint*)) +SDL_PROC_UNUSED(void,glColor3s,(GLshort,GLshort,GLshort)) +SDL_PROC_UNUSED(void,glColor3sv,(const GLshort*)) +SDL_PROC_UNUSED(void,glColor3ub,(GLubyte,GLubyte,GLubyte)) +SDL_PROC_UNUSED(void,glColor3ubv,(const GLubyte*)) +SDL_PROC_UNUSED(void,glColor3ui,(GLuint,GLuint,GLuint)) +SDL_PROC_UNUSED(void,glColor3uiv,(const GLuint*)) +SDL_PROC_UNUSED(void,glColor3us,(GLushort,GLushort,GLushort)) +SDL_PROC_UNUSED(void,glColor3usv,(const GLushort*)) +SDL_PROC_UNUSED(void,glColor4b,(GLbyte,GLbyte,GLbyte,GLbyte)) +SDL_PROC_UNUSED(void,glColor4bv,(const GLbyte*)) +SDL_PROC_UNUSED(void,glColor4d,(GLdouble,GLdouble,GLdouble,GLdouble)) +SDL_PROC_UNUSED(void,glColor4dv,(const GLdouble*)) +SDL_PROC(void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glColor4fv,(const GLfloat*)) +SDL_PROC_UNUSED(void,glColor4i,(GLint,GLint,GLint,GLint)) +SDL_PROC_UNUSED(void,glColor4iv,(const GLint*)) +SDL_PROC_UNUSED(void,glColor4s,(GLshort,GLshort,GLshort,GLshort)) +SDL_PROC_UNUSED(void,glColor4sv,(const GLshort*)) +SDL_PROC_UNUSED(void,glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) +SDL_PROC_UNUSED(void,glColor4ubv,(const GLubyte *v)) +SDL_PROC_UNUSED(void,glColor4ui,(GLuint red, GLuint green, GLuint blue, GLuint alpha)) +SDL_PROC_UNUSED(void,glColor4uiv,(const GLuint *v)) +SDL_PROC_UNUSED(void,glColor4us,(GLushort red, GLushort green, GLushort blue, GLushort alpha)) +SDL_PROC_UNUSED(void,glColor4usv,(const GLushort *v)) +SDL_PROC_UNUSED(void,glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) +SDL_PROC_UNUSED(void,glColorMaterial,(GLenum face, GLenum mode)) +SDL_PROC_UNUSED(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) +SDL_PROC_UNUSED(void,glCopyTexImage1D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)) +SDL_PROC_UNUSED(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) +SDL_PROC_UNUSED(void,glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) +SDL_PROC_UNUSED(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +SDL_PROC_UNUSED(void,glCullFace,(GLenum mode)) +SDL_PROC_UNUSED(void,glDeleteLists,(GLuint list, GLsizei range)) +SDL_PROC_UNUSED(void,glDeleteTextures,(GLsizei n, const GLuint *textures)) +SDL_PROC_UNUSED(void,glDepthFunc,(GLenum func)) +SDL_PROC_UNUSED(void,glDepthMask,(GLboolean flag)) +SDL_PROC_UNUSED(void,glDepthRange,(GLclampd zNear, GLclampd zFar)) +SDL_PROC(void,glDisable,(GLenum cap)) +SDL_PROC_UNUSED(void,glDisableClientState,(GLenum array)) +SDL_PROC_UNUSED(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count)) +SDL_PROC_UNUSED(void,glDrawBuffer,(GLenum mode)) +SDL_PROC_UNUSED(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) +SDL_PROC_UNUSED(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glEdgeFlag,(GLboolean flag)) +SDL_PROC_UNUSED(void,glEdgeFlagPointer,(GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glEdgeFlagv,(const GLboolean *flag)) +SDL_PROC(void,glEnable,(GLenum cap)) +SDL_PROC_UNUSED(void,glEnableClientState,(GLenum array)) +SDL_PROC(void,glEnd,(void)) +SDL_PROC_UNUSED(void,glEndList,(void)) +SDL_PROC_UNUSED(void,glEvalCoord1d,(GLdouble u)) +SDL_PROC_UNUSED(void,glEvalCoord1dv,(const GLdouble *u)) +SDL_PROC_UNUSED(void,glEvalCoord1f,(GLfloat u)) +SDL_PROC_UNUSED(void,glEvalCoord1fv,(const GLfloat *u)) +SDL_PROC_UNUSED(void,glEvalCoord2d,(GLdouble u, GLdouble v)) +SDL_PROC_UNUSED(void,glEvalCoord2dv,(const GLdouble *u)) +SDL_PROC_UNUSED(void,glEvalCoord2f,(GLfloat u, GLfloat v)) +SDL_PROC_UNUSED(void,glEvalCoord2fv,(const GLfloat *u)) +SDL_PROC_UNUSED(void,glEvalMesh1,(GLenum mode, GLint i1, GLint i2)) +SDL_PROC_UNUSED(void,glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) +SDL_PROC_UNUSED(void,glEvalPoint1,(GLint i)) +SDL_PROC_UNUSED(void,glEvalPoint2,(GLint i, GLint j)) +SDL_PROC_UNUSED(void,glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer)) +SDL_PROC_UNUSED(void,glFinish,(void)) +SDL_PROC(void,glFlush,(void)) +SDL_PROC_UNUSED(void,glFogf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glFogfv,(GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glFogi,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glFogiv,(GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glFrontFace,(GLenum mode)) +SDL_PROC_UNUSED(void,glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +SDL_PROC_UNUSED(GLuint,glGenLists,(GLsizei range)) +SDL_PROC(void,glGenTextures,(GLsizei n, GLuint *textures)) +SDL_PROC_UNUSED(void,glGetBooleanv,(GLenum pname, GLboolean *params)) +SDL_PROC_UNUSED(void,glGetClipPlane,(GLenum plane, GLdouble *equation)) +SDL_PROC_UNUSED(void,glGetDoublev,(GLenum pname, GLdouble *params)) +SDL_PROC_UNUSED(GLenum,glGetError,(void)) +SDL_PROC_UNUSED(void,glGetFloatv,(GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetIntegerv,(GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetLightiv,(GLenum light, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetMapdv,(GLenum target, GLenum query, GLdouble *v)) +SDL_PROC_UNUSED(void,glGetMapfv,(GLenum target, GLenum query, GLfloat *v)) +SDL_PROC_UNUSED(void,glGetMapiv,(GLenum target, GLenum query, GLint *v)) +SDL_PROC_UNUSED(void,glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetMaterialiv,(GLenum face, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetPixelMapfv,(GLenum map, GLfloat *values)) +SDL_PROC_UNUSED(void,glGetPixelMapuiv,(GLenum map, GLuint *values)) +SDL_PROC_UNUSED(void,glGetPixelMapusv,(GLenum map, GLushort *values)) +SDL_PROC_UNUSED(void,glGetPointerv,(GLenum pname, GLvoid* *params)) +SDL_PROC_UNUSED(void,glGetPolygonStipple,(GLubyte *mask)) +SDL_PROC(const GLubyte *,glGetString,(GLenum name)) +SDL_PROC_UNUSED(void,glGetTexEnvfv,(GLenum target, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexEnviv,(GLenum target, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexGendv,(GLenum coord, GLenum pname, GLdouble *params)) +SDL_PROC_UNUSED(void,glGetTexGenfv,(GLenum coord, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexGeniv,(GLenum coord, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) +SDL_PROC_UNUSED(void,glGetTexLevelParameterfv,(GLenum target, GLint level, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexParameterfv,(GLenum target, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexParameteriv,(GLenum target, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glHint,(GLenum target, GLenum mode)) +SDL_PROC_UNUSED(void,glIndexMask,(GLuint mask)) +SDL_PROC_UNUSED(void,glIndexPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glIndexd,(GLdouble c)) +SDL_PROC_UNUSED(void,glIndexdv,(const GLdouble *c)) +SDL_PROC_UNUSED(void,glIndexf,(GLfloat c)) +SDL_PROC_UNUSED(void,glIndexfv,(const GLfloat *c)) +SDL_PROC_UNUSED(void,glIndexi,(GLint c)) +SDL_PROC_UNUSED(void,glIndexiv,(const GLint *c)) +SDL_PROC_UNUSED(void,glIndexs,(GLshort c)) +SDL_PROC_UNUSED(void,glIndexsv,(const GLshort *c)) +SDL_PROC_UNUSED(void,glIndexub,(GLubyte c)) +SDL_PROC_UNUSED(void,glIndexubv,(const GLubyte *c)) +SDL_PROC_UNUSED(void,glInitNames,(void)) +SDL_PROC_UNUSED(void,glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(GLboolean,glIsEnabled,(GLenum cap)) +SDL_PROC_UNUSED(GLboolean,glIsList,(GLuint list)) +SDL_PROC_UNUSED(GLboolean,glIsTexture,(GLuint texture)) +SDL_PROC_UNUSED(void,glLightModelf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glLightModelfv,(GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glLightModeli,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glLightModeliv,(GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glLightf,(GLenum light, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glLightfv,(GLenum light, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glLighti,(GLenum light, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glLightiv,(GLenum light, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glLineStipple,(GLint factor, GLushort pattern)) +SDL_PROC_UNUSED(void,glLineWidth,(GLfloat width)) +SDL_PROC_UNUSED(void,glListBase,(GLuint base)) +SDL_PROC(void,glLoadIdentity,(void)) +SDL_PROC_UNUSED(void,glLoadMatrixd,(const GLdouble *m)) +SDL_PROC_UNUSED(void,glLoadMatrixf,(const GLfloat *m)) +SDL_PROC_UNUSED(void,glLoadName,(GLuint name)) +SDL_PROC_UNUSED(void,glLogicOp,(GLenum opcode)) +SDL_PROC_UNUSED(void,glMap1d,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) +SDL_PROC_UNUSED(void,glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) +SDL_PROC_UNUSED(void,glMap2d,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) +SDL_PROC_UNUSED(void,glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) +SDL_PROC_UNUSED(void,glMapGrid1d,(GLint un, GLdouble u1, GLdouble u2)) +SDL_PROC_UNUSED(void,glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2)) +SDL_PROC_UNUSED(void,glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)) +SDL_PROC_UNUSED(void,glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)) +SDL_PROC_UNUSED(void,glMaterialf,(GLenum face, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glMateriali,(GLenum face, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glMaterialiv,(GLenum face, GLenum pname, const GLint *params)) +SDL_PROC(void,glMatrixMode,(GLenum mode)) +SDL_PROC_UNUSED(void,glMultMatrixd,(const GLdouble *m)) +SDL_PROC_UNUSED(void,glMultMatrixf,(const GLfloat *m)) +SDL_PROC_UNUSED(void,glNewList,(GLuint list, GLenum mode)) +SDL_PROC_UNUSED(void,glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz)) +SDL_PROC_UNUSED(void,glNormal3bv,(const GLbyte *v)) +SDL_PROC_UNUSED(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz)) +SDL_PROC_UNUSED(void,glNormal3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz)) +SDL_PROC_UNUSED(void,glNormal3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glNormal3i,(GLint nx, GLint ny, GLint nz)) +SDL_PROC_UNUSED(void,glNormal3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glNormal3s,(GLshort nx, GLshort ny, GLshort nz)) +SDL_PROC_UNUSED(void,glNormal3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +SDL_PROC_UNUSED(void,glPassThrough,(GLfloat token)) +SDL_PROC_UNUSED(void,glPixelMapfv,(GLenum map, GLsizei mapsize, const GLfloat *values)) +SDL_PROC_UNUSED(void,glPixelMapuiv,(GLenum map, GLsizei mapsize, const GLuint *values)) +SDL_PROC_UNUSED(void,glPixelMapusv,(GLenum map, GLsizei mapsize, const GLushort *values)) +SDL_PROC_UNUSED(void,glPixelStoref,(GLenum pname, GLfloat param)) +SDL_PROC(void,glPixelStorei,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glPixelTransferf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glPixelTransferi,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glPixelZoom,(GLfloat xfactor, GLfloat yfactor)) +SDL_PROC_UNUSED(void,glPointSize,(GLfloat size)) +SDL_PROC_UNUSED(void,glPolygonMode,(GLenum face, GLenum mode)) +SDL_PROC_UNUSED(void,glPolygonOffset,(GLfloat factor, GLfloat units)) +SDL_PROC_UNUSED(void,glPolygonStipple,(const GLubyte *mask)) +SDL_PROC(void,glPopAttrib,(void)) +SDL_PROC(void,glPopClientAttrib,(void)) +SDL_PROC(void,glPopMatrix,(void)) +SDL_PROC_UNUSED(void,glPopName,(void)) +SDL_PROC_UNUSED(void,glPrioritizeTextures,(GLsizei n, const GLuint *textures, const GLclampf *priorities)) +SDL_PROC(void,glPushAttrib,(GLbitfield mask)) +SDL_PROC(void,glPushClientAttrib,(GLbitfield mask)) +SDL_PROC(void,glPushMatrix,(void)) +SDL_PROC_UNUSED(void,glPushName,(GLuint name)) +SDL_PROC_UNUSED(void,glRasterPos2d,(GLdouble x, GLdouble y)) +SDL_PROC_UNUSED(void,glRasterPos2dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos2f,(GLfloat x, GLfloat y)) +SDL_PROC_UNUSED(void,glRasterPos2fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos2i,(GLint x, GLint y)) +SDL_PROC_UNUSED(void,glRasterPos2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos2s,(GLshort x, GLshort y)) +SDL_PROC_UNUSED(void,glRasterPos2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glRasterPos3d,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glRasterPos3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos3f,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glRasterPos3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos3i,(GLint x, GLint y, GLint z)) +SDL_PROC_UNUSED(void,glRasterPos3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos3s,(GLshort x, GLshort y, GLshort z)) +SDL_PROC_UNUSED(void,glRasterPos3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glRasterPos4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +SDL_PROC_UNUSED(void,glRasterPos4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +SDL_PROC_UNUSED(void,glRasterPos4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos4i,(GLint x, GLint y, GLint z, GLint w)) +SDL_PROC_UNUSED(void,glRasterPos4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w)) +SDL_PROC_UNUSED(void,glRasterPos4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glReadBuffer,(GLenum mode)) +SDL_PROC_UNUSED(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) +SDL_PROC_UNUSED(void,glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) +SDL_PROC_UNUSED(void,glRectdv,(const GLdouble *v1, const GLdouble *v2)) +SDL_PROC_UNUSED(void,glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) +SDL_PROC_UNUSED(void,glRectfv,(const GLfloat *v1, const GLfloat *v2)) +SDL_PROC_UNUSED(void,glRecti,(GLint x1, GLint y1, GLint x2, GLint y2)) +SDL_PROC_UNUSED(void,glRectiv,(const GLint *v1, const GLint *v2)) +SDL_PROC_UNUSED(void,glRects,(GLshort x1, GLshort y1, GLshort x2, GLshort y2)) +SDL_PROC_UNUSED(void,glRectsv,(const GLshort *v1, const GLshort *v2)) +SDL_PROC_UNUSED(GLint,glRenderMode,(GLenum mode)) +SDL_PROC_UNUSED(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glScaled,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glScalef,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height)) +SDL_PROC_UNUSED(void,glSelectBuffer,(GLsizei size, GLuint *buffer)) +SDL_PROC_UNUSED(void,glShadeModel,(GLenum mode)) +SDL_PROC_UNUSED(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask)) +SDL_PROC_UNUSED(void,glStencilMask,(GLuint mask)) +SDL_PROC_UNUSED(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass)) +SDL_PROC_UNUSED(void,glTexCoord1d,(GLdouble s)) +SDL_PROC_UNUSED(void,glTexCoord1dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord1f,(GLfloat s)) +SDL_PROC_UNUSED(void,glTexCoord1fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord1i,(GLint s)) +SDL_PROC_UNUSED(void,glTexCoord1iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord1s,(GLshort s)) +SDL_PROC_UNUSED(void,glTexCoord1sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord2d,(GLdouble s, GLdouble t)) +SDL_PROC_UNUSED(void,glTexCoord2dv,(const GLdouble *v)) +SDL_PROC(void,glTexCoord2f,(GLfloat s, GLfloat t)) +SDL_PROC_UNUSED(void,glTexCoord2fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord2i,(GLint s, GLint t)) +SDL_PROC_UNUSED(void,glTexCoord2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord2s,(GLshort s, GLshort t)) +SDL_PROC_UNUSED(void,glTexCoord2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord3d,(GLdouble s, GLdouble t, GLdouble r)) +SDL_PROC_UNUSED(void,glTexCoord3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord3f,(GLfloat s, GLfloat t, GLfloat r)) +SDL_PROC_UNUSED(void,glTexCoord3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord3i,(GLint s, GLint t, GLint r)) +SDL_PROC_UNUSED(void,glTexCoord3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord3s,(GLshort s, GLshort t, GLshort r)) +SDL_PROC_UNUSED(void,glTexCoord3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord4d,(GLdouble s, GLdouble t, GLdouble r, GLdouble q)) +SDL_PROC_UNUSED(void,glTexCoord4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord4f,(GLfloat s, GLfloat t, GLfloat r, GLfloat q)) +SDL_PROC_UNUSED(void,glTexCoord4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord4i,(GLint s, GLint t, GLint r, GLint q)) +SDL_PROC_UNUSED(void,glTexCoord4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord4s,(GLshort s, GLshort t, GLshort r, GLshort q)) +SDL_PROC_UNUSED(void,glTexCoord4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glTexEnvi,(GLenum target, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexEnviv,(GLenum target, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexGend,(GLenum coord, GLenum pname, GLdouble param)) +SDL_PROC_UNUSED(void,glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params)) +SDL_PROC_UNUSED(void,glTexGenf,(GLenum coord, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glTexGeni,(GLenum coord, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexGeniv,(GLenum coord, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexImage1D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glTexImage2D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params)) +SDL_PROC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexParameteriv,(GLenum target, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glVertex2d,(GLdouble x, GLdouble y)) +SDL_PROC_UNUSED(void,glVertex2dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex2f,(GLfloat x, GLfloat y)) +SDL_PROC_UNUSED(void,glVertex2fv,(const GLfloat *v)) +SDL_PROC(void,glVertex2i,(GLint x, GLint y)) +SDL_PROC_UNUSED(void,glVertex2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex2s,(GLshort x, GLshort y)) +SDL_PROC_UNUSED(void,glVertex2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertex3d,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glVertex3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glVertex3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glVertex3i,(GLint x, GLint y, GLint z)) +SDL_PROC_UNUSED(void,glVertex3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex3s,(GLshort x, GLshort y, GLshort z)) +SDL_PROC_UNUSED(void,glVertex3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertex4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +SDL_PROC_UNUSED(void,glVertex4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +SDL_PROC_UNUSED(void,glVertex4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glVertex4i,(GLint x, GLint y, GLint z, GLint w)) +SDL_PROC_UNUSED(void,glVertex4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex4s,(GLshort x, GLshort y, GLshort z, GLshort w)) +SDL_PROC_UNUSED(void,glVertex4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glViewport,(GLint x, GLint y, GLsizei width, GLsizei height)) diff --git a/apps/plugins/sdl/src/video/SDL_leaks.h b/apps/plugins/sdl/src/video/SDL_leaks.h new file mode 100644 index 0000000000..74495c63fe --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_leaks.h @@ -0,0 +1,31 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Define this if you want surface leak detection code enabled */ +/*#define CHECK_LEAKS*/ + +/* Global variables used to check leaks in code using SDL */ + +#ifdef CHECK_LEAKS +extern int surfaces_allocated; +#endif diff --git a/apps/plugins/sdl/src/video/SDL_pixels.c b/apps/plugins/sdl/src/video/SDL_pixels.c new file mode 100644 index 0000000000..1a7fd518f1 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_pixels.c @@ -0,0 +1,626 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* General (mostly internal) pixel/color manipulation routines for SDL */ + +#include "SDL_endian.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_RLEaccel_c.h" + +/* Helper functions */ +/* + * Allocate a pixel format structure and fill it according to the given info. + */ +SDL_PixelFormat *SDL_AllocFormat(int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_PixelFormat *format; + Uint32 mask; + + /* Allocate an empty pixel format structure */ + format = SDL_malloc(sizeof(*format)); + if ( format == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + SDL_memset(format, 0, sizeof(*format)); + format->alpha = SDL_ALPHA_OPAQUE; + + /* Set up the format */ + format->BitsPerPixel = bpp; + format->BytesPerPixel = (bpp+7)/8; + if ( Rmask || Bmask || Gmask ) { /* Packed pixels with custom mask */ + format->palette = NULL; + format->Rshift = 0; + format->Rloss = 8; + if ( Rmask ) { + for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) + ++format->Rshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Rloss; + } + format->Gshift = 0; + format->Gloss = 8; + if ( Gmask ) { + for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) + ++format->Gshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Gloss; + } + format->Bshift = 0; + format->Bloss = 8; + if ( Bmask ) { + for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) + ++format->Bshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Bloss; + } + format->Ashift = 0; + format->Aloss = 8; + if ( Amask ) { + for ( mask = Amask; !(mask&0x01); mask >>= 1 ) + ++format->Ashift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Aloss; + } + format->Rmask = Rmask; + format->Gmask = Gmask; + format->Bmask = Bmask; + format->Amask = Amask; + } else if ( bpp > 8 ) { /* Packed pixels with standard mask */ + /* R-G-B */ + if ( bpp > 24 ) + bpp = 24; + format->Rloss = 8-(bpp/3); + format->Gloss = 8-(bpp/3)-(bpp%3); + format->Bloss = 8-(bpp/3); + format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); + format->Gshift = (bpp/3); + format->Bshift = 0; + format->Rmask = ((0xFF>>format->Rloss)<Rshift); + format->Gmask = ((0xFF>>format->Gloss)<Gshift); + format->Bmask = ((0xFF>>format->Bloss)<Bshift); + } else { + /* Palettized formats have no mask info */ + format->Rloss = 8; + format->Gloss = 8; + format->Bloss = 8; + format->Aloss = 8; + format->Rshift = 0; + format->Gshift = 0; + format->Bshift = 0; + format->Ashift = 0; + format->Rmask = 0; + format->Gmask = 0; + format->Bmask = 0; + format->Amask = 0; + } + if ( bpp <= 8 ) { /* Palettized mode */ + int ncolors = 1<palette = (SDL_Palette *)SDL_malloc(sizeof(SDL_Palette)); + if ( format->palette == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + (format->palette)->ncolors = ncolors; + (format->palette)->colors = (SDL_Color *)SDL_malloc( + (format->palette)->ncolors*sizeof(SDL_Color)); + if ( (format->palette)->colors == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + if ( Rmask || Bmask || Gmask ) { + /* create palette according to masks */ + int i; + int Rm=0,Gm=0,Bm=0; + int Rw=0,Gw=0,Bw=0; +#ifdef ENABLE_PALETTE_ALPHA + int Am=0,Aw=0; +#endif + if(Rmask) + { + Rw=8-format->Rloss; + for(i=format->Rloss;i>0;i-=Rw) + Rm|=1<Gloss; + for(i=format->Gloss;i>0;i-=Gw) + Gm|=1<Bloss; + for(i=format->Bloss;i>0;i-=Bw) + Bm|=1<Aloss; + for(i=format->Aloss;i>0;i-=Aw) + Am|=1<>format->Rshift; + r=(r<Rloss)|((r*Rm)>>Rw); + format->palette->colors[i].r=r; + + g=(i&Gmask)>>format->Gshift; + g=(g<Gloss)|((g*Gm)>>Gw); + format->palette->colors[i].g=g; + + b=(i&Bmask)>>format->Bshift; + b=(b<Bloss)|((b*Bm)>>Bw); + format->palette->colors[i].b=b; + +#ifdef ENABLE_PALETTE_ALPHA + a=(i&Amask)>>format->Ashift; + a=(a<Aloss)|((a*Am)>>Aw); + format->palette->colors[i].unused=a; +#else + format->palette->colors[i].unused=0; +#endif + } + } else if ( ncolors == 2 ) { + /* Create a black and white bitmap palette */ + format->palette->colors[0].r = 0xFF; + format->palette->colors[0].g = 0xFF; + format->palette->colors[0].b = 0xFF; + format->palette->colors[1].r = 0x00; + format->palette->colors[1].g = 0x00; + format->palette->colors[1].b = 0x00; + } else { + /* Create an empty palette */ + SDL_memset((format->palette)->colors, 0, + (format->palette)->ncolors*sizeof(SDL_Color)); + } + } + return(format); +} +SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + if ( surface->format ) { + SDL_FreeFormat(surface->format); + SDL_FormatChanged(surface); + } + surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); + return surface->format; +} + +/* + * Change any previous mappings from/to the new surface format + */ +void SDL_FormatChanged(SDL_Surface *surface) +{ + static int format_version = 0; + ++format_version; + if ( format_version < 0 ) { /* It wrapped... */ + format_version = 1; + } + surface->format_version = format_version; + SDL_InvalidateMap(surface->map); +} +/* + * Free a previously allocated format structure + */ +void SDL_FreeFormat(SDL_PixelFormat *format) +{ + if ( format ) { + if ( format->palette ) { + if ( format->palette->colors ) { + SDL_free(format->palette->colors); + } + SDL_free(format->palette); + } + SDL_free(format); + } +} +/* + * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors + */ +void SDL_DitherColors(SDL_Color *colors, int bpp) +{ + int i; + if(bpp != 8) + return; /* only 8bpp supported right now */ + + for(i = 0; i < 256; i++) { + int r, g, b; + /* map each bit field to the full [0, 255] interval, + so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ + r = i & 0xe0; + r |= r >> 3 | r >> 6; + colors[i].r = r; + g = (i << 3) & 0xe0; + g |= g >> 3 | g >> 6; + colors[i].g = g; + b = i & 0x3; + b |= b << 2; + b |= b << 4; + colors[i].b = b; + } +} +/* + * Calculate the pad-aligned scanline width of a surface + */ +Uint16 SDL_CalculatePitch(SDL_Surface *surface) +{ + Uint16 pitch; + + /* Surface should be 4-byte aligned for speed */ + pitch = surface->w*surface->format->BytesPerPixel; + switch (surface->format->BitsPerPixel) { + case 1: + pitch = (pitch+7)/8; + break; + case 4: + pitch = (pitch+1)/2; + break; + default: + break; + } + pitch = (pitch + 3) & ~3; /* 4-byte aligning */ + return(pitch); +} +/* + * Match an RGB value to a particular palette index + */ +Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) +{ + /* Do colorspace distance matching */ + unsigned int smallest; + unsigned int distance; + int rd, gd, bd; + int i; + Uint8 pixel=0; + + smallest = ~0; + for ( i=0; incolors; ++i ) { + rd = pal->colors[i].r - r; + gd = pal->colors[i].g - g; + bd = pal->colors[i].b - b; + distance = (rd*rd)+(gd*gd)+(bd*bd); + if ( distance < smallest ) { + pixel = i; + if ( distance == 0 ) { /* Perfect match! */ + break; + } + smallest = distance; + } + } + return(pixel); +} + +/* Find the opaque pixel value corresponding to an RGB triple */ +Uint32 SDL_MapRGB +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b) +{ + if ( format->palette == NULL ) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift + | format->Amask; + } else { + return SDL_FindColor(format->palette, r, g, b); + } +} + +/* Find the pixel value corresponding to an RGBA quadruple */ +Uint32 SDL_MapRGBA +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a) +{ + if ( format->palette == NULL ) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift + | ((a >> format->Aloss) << format->Ashift & format->Amask); + } else { + return SDL_FindColor(format->palette, r, g, b); + } +} + +void SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * const fmt, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) +{ + if ( fmt->palette == NULL ) { + /* + * This makes sure that the result is mapped to the + * interval [0..255], and the maximum value for each + * component is 255. This is important to make sure + * that white is indeed reported as (255, 255, 255), + * and that opaque alpha is 255. + * This only works for RGB bit fields at least 4 bit + * wide, which is almost always the case. + */ + unsigned v; + v = (pixel & fmt->Rmask) >> fmt->Rshift; + *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); + v = (pixel & fmt->Gmask) >> fmt->Gshift; + *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); + v = (pixel & fmt->Bmask) >> fmt->Bshift; + *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); + if(fmt->Amask) { + v = (pixel & fmt->Amask) >> fmt->Ashift; + *a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1))); + } else { + *a = SDL_ALPHA_OPAQUE; + } + } else { + *r = fmt->palette->colors[pixel].r; + *g = fmt->palette->colors[pixel].g; + *b = fmt->palette->colors[pixel].b; + *a = SDL_ALPHA_OPAQUE; + } +} + +void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * const fmt, + Uint8 *r,Uint8 *g,Uint8 *b) +{ + if ( fmt->palette == NULL ) { + /* the note for SDL_GetRGBA above applies here too */ + unsigned v; + v = (pixel & fmt->Rmask) >> fmt->Rshift; + *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); + v = (pixel & fmt->Gmask) >> fmt->Gshift; + *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); + v = (pixel & fmt->Bmask) >> fmt->Bshift; + *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); + } else { + *r = fmt->palette->colors[pixel].r; + *g = fmt->palette->colors[pixel].g; + *b = fmt->palette->colors[pixel].b; + } +} + +/* Apply gamma to a set of colors - this is easy. :) */ +void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, + int ncolors) +{ + int i; + + for ( i=0; i> 8; + output[i].g = gamma[1*256 + colors[i].g] >> 8; + output[i].b = gamma[2*256 + colors[i].b] >> 8; + } +} + +/* Map from Palette to Palette */ +static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) +{ + Uint8 *map; + int i; + + if ( identical ) { + if ( src->ncolors <= dst->ncolors ) { + /* If an identical palette, no need to map */ + if ( SDL_memcmp(src->colors, dst->colors, src->ncolors* + sizeof(SDL_Color)) == 0 ) { + *identical = 1; + return(NULL); + } + } + *identical = 0; + } + map = (Uint8 *)SDL_malloc(src->ncolors); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + for ( i=0; incolors; ++i ) { + map[i] = SDL_FindColor(dst, + src->colors[i].r, src->colors[i].g, src->colors[i].b); + } + return(map); +} +/* Map from Palette to BitField */ +static Uint8 *Map1toN(SDL_PixelFormat *src, SDL_PixelFormat *dst) +{ + Uint8 *map; + int i; + int bpp; + unsigned alpha; + SDL_Palette *pal = src->palette; + + bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); + map = (Uint8 *)SDL_malloc(pal->ncolors*bpp); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + + alpha = dst->Amask ? src->alpha : 0; + /* We memory copy to the pixel map so the endianness is preserved */ + for ( i=0; incolors; ++i ) { + ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, + pal->colors[i].r, pal->colors[i].g, + pal->colors[i].b, alpha); + } + return(map); +} +/* Map from BitField to Dithered-Palette to Palette */ +static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_PixelFormat *dst, int *identical) +{ + /* Generate a 256 color dither palette */ + SDL_Palette dithered; + SDL_Color colors[256]; + SDL_Palette *pal = dst->palette; + + /* SDL_DitherColors does not initialize the 'unused' component of colors, + but Map1to1 compares it against pal, so we should initialize it. */ + SDL_memset(colors, 0, sizeof(colors)); + + dithered.ncolors = 256; + SDL_DitherColors(colors, 8); + dithered.colors = colors; + return(Map1to1(&dithered, pal, identical)); +} + +SDL_BlitMap *SDL_AllocBlitMap(void) +{ + SDL_BlitMap *map; + + /* Allocate the empty map */ + map = (SDL_BlitMap *)SDL_malloc(sizeof(*map)); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + SDL_memset(map, 0, sizeof(*map)); + + /* Allocate the software blit data */ + map->sw_data = (struct private_swaccel *)SDL_malloc(sizeof(*map->sw_data)); + if ( map->sw_data == NULL ) { + SDL_FreeBlitMap(map); + SDL_OutOfMemory(); + return(NULL); + } + SDL_memset(map->sw_data, 0, sizeof(*map->sw_data)); + + /* It's ready to go */ + return(map); +} +void SDL_InvalidateMap(SDL_BlitMap *map) +{ + if ( ! map ) { + return; + } + map->dst = NULL; + map->format_version = (unsigned int)-1; + if ( map->table ) { + SDL_free(map->table); + map->table = NULL; + } +} +int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) +{ + SDL_PixelFormat *srcfmt; + SDL_PixelFormat *dstfmt; + SDL_BlitMap *map; + + /* Clear out any previous mapping */ + map = src->map; + if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(src, 1); + } + SDL_InvalidateMap(map); + + /* Figure out what kind of mapping we're doing */ + map->identity = 0; + srcfmt = src->format; + dstfmt = dst->format; + switch (srcfmt->BytesPerPixel) { + case 1: + switch (dstfmt->BytesPerPixel) { + case 1: + /* Palette --> Palette */ + /* If both SDL_HWSURFACE, assume have same palette */ + if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && + ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { + map->identity = 1; + } else { + map->table = Map1to1(srcfmt->palette, + dstfmt->palette, &map->identity); + } + if ( ! map->identity ) { + if ( map->table == NULL ) { + return(-1); + } + } + if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) + map->identity = 0; + break; + + default: + /* Palette --> BitField */ + map->table = Map1toN(srcfmt, dstfmt); + if ( map->table == NULL ) { + return(-1); + } + break; + } + break; + default: + switch (dstfmt->BytesPerPixel) { + case 1: + /* BitField --> Palette */ + map->table = MapNto1(srcfmt, dstfmt, &map->identity); + if ( ! map->identity ) { + if ( map->table == NULL ) { + return(-1); + } + } + map->identity = 0; /* Don't optimize to copy */ + break; + default: + /* BitField --> BitField */ + if ( FORMAT_EQUAL(srcfmt, dstfmt) ) + map->identity = 1; + break; + } + break; + } + + map->dst = dst; + map->format_version = dst->format_version; + + /* Choose your blitters wisely */ + return(SDL_CalculateBlit(src)); +} +void SDL_FreeBlitMap(SDL_BlitMap *map) +{ + if ( map ) { + SDL_InvalidateMap(map); + if ( map->sw_data != NULL ) { + SDL_free(map->sw_data); + } + SDL_free(map); + } +} diff --git a/apps/plugins/sdl/src/video/SDL_pixels_c.h b/apps/plugins/sdl/src/video/SDL_pixels_c.h new file mode 100644 index 0000000000..76759e2f7f --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_pixels_c.h @@ -0,0 +1,46 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Useful functions and variables from SDL_pixel.c */ + +#include "SDL_blit.h" + +/* Pixel format functions */ +extern SDL_PixelFormat *SDL_AllocFormat(int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern void SDL_FormatChanged(SDL_Surface *surface); +extern void SDL_FreeFormat(SDL_PixelFormat *format); + +/* Blit mapping functions */ +extern SDL_BlitMap *SDL_AllocBlitMap(void); +extern void SDL_InvalidateMap(SDL_BlitMap *map); +extern int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst); +extern void SDL_FreeBlitMap(SDL_BlitMap *map); + +/* Miscellaneous functions */ +extern Uint16 SDL_CalculatePitch(SDL_Surface *surface); +extern void SDL_DitherColors(SDL_Color *colors, int bpp); +extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b); +extern void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, int ncolors); diff --git a/apps/plugins/sdl/src/video/SDL_stretch.c b/apps/plugins/sdl/src/video/SDL_stretch.c new file mode 100644 index 0000000000..7ce401ff7a --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_stretch.c @@ -0,0 +1,358 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This a stretch blit implementation based on ideas given to me by + Tomasz Cejner - thanks! :) + + April 27, 2000 - Sam Lantinga +*/ + +#include "SDL_video.h" +#include "SDL_blit.h" + +/* This isn't ready for general consumption yet - it should be folded + into the general blitting mechanism. +*/ + +#if ((defined(_MFC_VER) && defined(_M_IX86)/* && !defined(_WIN32_WCE) still needed? */) || \ + defined(__WATCOMC__) || \ + (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES +/* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct + * value after the first scanline. FIXME? */ +/*#define USE_ASM_STRETCH*/ +#endif + +#ifdef USE_ASM_STRETCH + +#ifdef HAVE_MPROTECT +#include +#include +#endif +#ifdef __GNUC__ +#define PAGE_ALIGNED __attribute__((__aligned__(4096))) +#else +#define PAGE_ALIGNED +#endif + +#if defined(_M_IX86) || defined(i386) +#define PREFIX16 0x66 +#define STORE_BYTE 0xAA +#define STORE_WORD 0xAB +#define LOAD_BYTE 0xAC +#define LOAD_WORD 0xAD +#define RETURN 0xC3 +#else +#error Need assembly opcodes for this architecture +#endif + +static unsigned char copy_row[4096] PAGE_ALIGNED; + +static int generate_rowbytes(int src_w, int dst_w, int bpp) +{ + static struct { + int bpp; + int src_w; + int dst_w; + int status; + } last; + + int i; + int pos, inc; + unsigned char *eip, *fence; + unsigned char load, store; + + /* See if we need to regenerate the copy buffer */ + if ( (src_w == last.src_w) && + (dst_w == last.dst_w) && (bpp == last.bpp) ) { + return(last.status); + } + last.bpp = bpp; + last.src_w = src_w; + last.dst_w = dst_w; + last.status = -1; + + switch (bpp) { + case 1: + load = LOAD_BYTE; + store = STORE_BYTE; + break; + case 2: + case 4: + load = LOAD_WORD; + store = STORE_WORD; + break; + default: + SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp); + return(-1); + } +#ifdef HAVE_MPROTECT + /* Make the code writeable */ + if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_WRITE) < 0 ) { + SDL_SetError("Couldn't make copy buffer writeable"); + return(-1); + } +#endif + pos = 0x10000; + inc = (src_w << 16) / dst_w; + eip = copy_row; + fence = copy_row+sizeof(copy_row)-2; + for ( i=0; i= 0x10000L ) { + if ( eip == fence ) { + return -1; + } + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = load; + pos -= 0x10000L; + } + if ( eip == fence ) { + return -1; + } + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = store; + pos += inc; + } + *eip++ = RETURN; + +#ifdef HAVE_MPROTECT + /* Make the code executable but not writeable */ + if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_EXEC) < 0 ) { + SDL_SetError("Couldn't make copy buffer executable"); + return(-1); + } +#endif + last.status = 0; + return(0); +} + +#endif /* USE_ASM_STRETCH */ + +#define DEFINE_COPY_ROW(name, type) \ +void name(type *src, int src_w, type *dst, int dst_w) \ +{ \ + int i; \ + int pos, inc; \ + type pixel = 0; \ + \ + pos = 0x10000; \ + inc = (src_w << 16) / dst_w; \ + for ( i=dst_w; i>0; --i ) { \ + while ( pos >= 0x10000L ) { \ + pixel = *src++; \ + pos -= 0x10000L; \ + } \ + *dst++ = pixel; \ + pos += inc; \ + } \ +} +DEFINE_COPY_ROW(copy_row1, Uint8) +DEFINE_COPY_ROW(copy_row2, Uint16) +DEFINE_COPY_ROW(copy_row4, Uint32) + +/* The ASM code doesn't handle 24-bpp stretch blits */ +void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w) +{ + int i; + int pos, inc; + Uint8 pixel[3] = { 0, 0, 0 }; + + pos = 0x10000; + inc = (src_w << 16) / dst_w; + for ( i=dst_w; i>0; --i ) { + while ( pos >= 0x10000L ) { + pixel[0] = *src++; + pixel[1] = *src++; + pixel[2] = *src++; + pos -= 0x10000L; + } + *dst++ = pixel[0]; + *dst++ = pixel[1]; + *dst++ = pixel[2]; + pos += inc; + } +} + +/* Perform a stretch blit between two surfaces of the same format. + NOTE: This function is not safe to call from multiple threads! +*/ +int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int src_locked; + int dst_locked; + int pos, inc; + int dst_maxrow; + int src_row, dst_row; + Uint8 *srcp = NULL; + Uint8 *dstp; + SDL_Rect full_src; + SDL_Rect full_dst; +#ifdef USE_ASM_STRETCH + SDL_bool use_asm = SDL_TRUE; +#ifdef __GNUC__ + int u1, u2; +#endif +#endif /* USE_ASM_STRETCH */ + const int bpp = dst->format->BytesPerPixel; + + if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) { + SDL_SetError("Only works with same format surfaces"); + return(-1); + } + + /* Verify the blit rectangles */ + if ( srcrect ) { + if ( (srcrect->x < 0) || (srcrect->y < 0) || + ((srcrect->x+srcrect->w) > src->w) || + ((srcrect->y+srcrect->h) > src->h) ) { + SDL_SetError("Invalid source blit rectangle"); + return(-1); + } + } else { + full_src.x = 0; + full_src.y = 0; + full_src.w = src->w; + full_src.h = src->h; + srcrect = &full_src; + } + if ( dstrect ) { + if ( (dstrect->x < 0) || (dstrect->y < 0) || + ((dstrect->x+dstrect->w) > dst->w) || + ((dstrect->y+dstrect->h) > dst->h) ) { + SDL_SetError("Invalid destination blit rectangle"); + return(-1); + } + } else { + full_dst.x = 0; + full_dst.y = 0; + full_dst.w = dst->w; + full_dst.h = dst->h; + dstrect = &full_dst; + } + + /* Lock the destination if it's in hardware */ + dst_locked = 0; + if ( SDL_MUSTLOCK(dst) ) { + if ( SDL_LockSurface(dst) < 0 ) { + SDL_SetError("Unable to lock destination surface"); + return(-1); + } + dst_locked = 1; + } + /* Lock the source if it's in hardware */ + src_locked = 0; + if ( SDL_MUSTLOCK(src) ) { + if ( SDL_LockSurface(src) < 0 ) { + if ( dst_locked ) { + SDL_UnlockSurface(dst); + } + SDL_SetError("Unable to lock source surface"); + return(-1); + } + src_locked = 1; + } + + /* Set up the data... */ + pos = 0x10000; + inc = (srcrect->h << 16) / dstrect->h; + src_row = srcrect->y; + dst_row = dstrect->y; + +#ifdef USE_ASM_STRETCH + /* Write the opcodes for this stretch */ + if ( (bpp == 3) || + (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) { + use_asm = SDL_FALSE; + } +#endif + + /* Perform the stretch blit */ + for ( dst_maxrow = dst_row+dstrect->h; dst_rowpixels + (dst_row*dst->pitch) + + (dstrect->x*bpp); + while ( pos >= 0x10000L ) { + srcp = (Uint8 *)src->pixels + (src_row*src->pitch) + + (srcrect->x*bpp); + ++src_row; + pos -= 0x10000L; + } +#ifdef USE_ASM_STRETCH + if (use_asm) { +#ifdef __GNUC__ + __asm__ __volatile__ ( + "call *%4" + : "=&D" (u1), "=&S" (u2) + : "0" (dstp), "1" (srcp), "r" (copy_row) + : "memory" ); +#elif defined(_MSC_VER) || defined(__WATCOMC__) + { void *code = copy_row; + __asm { + push edi + push esi + + mov edi, dstp + mov esi, srcp + call dword ptr code + + pop esi + pop edi + } + } +#else +#error Need inline assembly for this compiler +#endif + } else +#endif + switch (bpp) { + case 1: + copy_row1(srcp, srcrect->w, dstp, dstrect->w); + break; + case 2: + copy_row2((Uint16 *)srcp, srcrect->w, + (Uint16 *)dstp, dstrect->w); + break; + case 3: + copy_row3(srcp, srcrect->w, dstp, dstrect->w); + break; + case 4: + copy_row4((Uint32 *)srcp, srcrect->w, + (Uint32 *)dstp, dstrect->w); + break; + } + pos += inc; + } + + /* We need to unlock the surfaces if they're locked */ + if ( dst_locked ) { + SDL_UnlockSurface(dst); + } + if ( src_locked ) { + SDL_UnlockSurface(src); + } + return(0); +} + diff --git a/apps/plugins/sdl/src/video/SDL_stretch_c.h b/apps/plugins/sdl/src/video/SDL_stretch_c.h new file mode 100644 index 0000000000..4cc6acb207 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_stretch_c.h @@ -0,0 +1,29 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Perform a stretch blit between two surfaces of the same format. + NOTE: This function is not safe to call from multiple threads! +*/ +extern int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + diff --git a/apps/plugins/sdl/src/video/SDL_surface.c b/apps/plugins/sdl/src/video/SDL_surface.c new file mode 100644 index 0000000000..0f3ad12c4b --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_surface.c @@ -0,0 +1,941 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_cursor_c.h" +#include "SDL_blit.h" +#include "SDL_RLEaccel_c.h" +#include "SDL_pixels_c.h" +#include "SDL_leaks.h" + + +/* Public routines */ +/* + * Create an empty RGB surface of the appropriate depth + */ +SDL_Surface * SDL_CreateRGBSurface (Uint32 flags, + int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Surface *screen; + SDL_Surface *surface; + + /* Make sure the size requested doesn't overflow our datatypes */ + /* Next time I write a library like SDL, I'll use int for size. :) */ + if ( width >= 16384 || height >= 65536 ) { + SDL_SetError("Width or height is too large"); + return(NULL); + } + + /* Check to see if we desire the surface in video memory */ + if ( video ) { + screen = SDL_PublicSurface; + } else { + screen = NULL; + } + if ( screen && ((screen->flags&SDL_HWSURFACE) == SDL_HWSURFACE) ) { + if ( (flags&(SDL_SRCCOLORKEY|SDL_SRCALPHA)) != 0 ) { + flags |= SDL_HWSURFACE; + } + if ( (flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + if ( ! current_video->info.blit_hw_CC ) { + flags &= ~SDL_HWSURFACE; + } + } + if ( (flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + if ( ! current_video->info.blit_hw_A ) { + flags &= ~SDL_HWSURFACE; + } + } + } else { + flags &= ~SDL_HWSURFACE; + } + + /* Allocate the surface */ + surface = (SDL_Surface *)SDL_malloc(sizeof(*surface)); + if ( surface == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + surface->flags = SDL_SWSURFACE; + if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + if ((Amask) && (video->displayformatalphapixel)) + { + depth = video->displayformatalphapixel->BitsPerPixel; + Rmask = video->displayformatalphapixel->Rmask; + Gmask = video->displayformatalphapixel->Gmask; + Bmask = video->displayformatalphapixel->Bmask; + Amask = video->displayformatalphapixel->Amask; + } + else + { + depth = screen->format->BitsPerPixel; + Rmask = screen->format->Rmask; + Gmask = screen->format->Gmask; + Bmask = screen->format->Bmask; + Amask = screen->format->Amask; + } + } + surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask); + if ( surface->format == NULL ) { + SDL_free(surface); + return(NULL); + } + if ( Amask ) { + surface->flags |= SDL_SRCALPHA; + } + surface->w = width; + surface->h = height; + surface->pitch = SDL_CalculatePitch(surface); + surface->pixels = NULL; + surface->offset = 0; + surface->hwdata = NULL; + surface->locked = 0; + surface->map = NULL; + surface->unused1 = 0; + SDL_SetClipRect(surface, NULL); + SDL_FormatChanged(surface); + + /* Get the pixels */ + if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) || + (video->AllocHWSurface(this, surface) < 0) ) { + if ( surface->w && surface->h ) { + surface->pixels = SDL_malloc(surface->h*surface->pitch); + if ( surface->pixels == NULL ) { + SDL_FreeSurface(surface); + SDL_OutOfMemory(); + return(NULL); + } + /* This is important for bitmaps */ + SDL_memset(surface->pixels, 0, surface->h*surface->pitch); + } + } + + /* Allocate an empty mapping */ + surface->map = SDL_AllocBlitMap(); + if ( surface->map == NULL ) { + SDL_FreeSurface(surface); + return(NULL); + } + + /* The surface is ready to go */ + surface->refcount = 1; +#ifdef CHECK_LEAKS + ++surfaces_allocated; +#endif + return(surface); +} +/* + * Create an RGB surface from an existing memory buffer + */ +SDL_Surface * SDL_CreateRGBSurfaceFrom (void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_Surface *surface; + + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth, + Rmask, Gmask, Bmask, Amask); + if ( surface != NULL ) { + surface->flags |= SDL_PREALLOC; + surface->pixels = pixels; + surface->w = width; + surface->h = height; + surface->pitch = pitch; + SDL_SetClipRect(surface, NULL); + } + return(surface); +} +/* + * Set the color key in a blittable surface + */ +int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) +{ + /* Sanity check the flag as it gets passed in */ + if ( flag & SDL_SRCCOLORKEY ) { + if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { + flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); + } else { + flag = SDL_SRCCOLORKEY; + } + } else { + flag = 0; + } + + /* Optimize away operations that don't change anything */ + if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && + (key == surface->format->colorkey) ) { + return(0); + } + + /* UnRLE surfaces before we change the colorkey */ + if ( surface->flags & SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + + if ( flag ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + + surface->flags |= SDL_SRCCOLORKEY; + surface->format->colorkey = key; + if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + if ( (video->SetHWColorKey == NULL) || + (video->SetHWColorKey(this, surface, key) < 0) ) { + surface->flags &= ~SDL_HWACCEL; + } + } + if ( flag & SDL_RLEACCELOK ) { + surface->flags |= SDL_RLEACCELOK; + } else { + surface->flags &= ~SDL_RLEACCELOK; + } + } else { + surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); + surface->format->colorkey = 0; + } + SDL_InvalidateMap(surface->map); + return(0); +} +/* This function sets the alpha channel of a surface */ +int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value) +{ + Uint32 oldflags = surface->flags; + Uint32 oldalpha = surface->format->alpha; + + /* Sanity check the flag as it gets passed in */ + if ( flag & SDL_SRCALPHA ) { + if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { + flag = (SDL_SRCALPHA | SDL_RLEACCELOK); + } else { + flag = SDL_SRCALPHA; + } + } else { + flag = 0; + } + + /* Optimize away operations that don't change anything */ + if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) && + (!flag || value == oldalpha) ) { + return(0); + } + + if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) + SDL_UnRLESurface(surface, 1); + + if ( flag ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + surface->flags |= SDL_SRCALPHA; + surface->format->alpha = value; + if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + if ( (video->SetHWAlpha == NULL) || + (video->SetHWAlpha(this, surface, value) < 0) ) { + surface->flags &= ~SDL_HWACCEL; + } + } + if ( flag & SDL_RLEACCELOK ) { + surface->flags |= SDL_RLEACCELOK; + } else { + surface->flags &= ~SDL_RLEACCELOK; + } + } else { + surface->flags &= ~SDL_SRCALPHA; + surface->format->alpha = SDL_ALPHA_OPAQUE; + } + /* + * The representation for software surfaces is independent of + * per-surface alpha, so no need to invalidate the blit mapping + * if just the alpha value was changed. (If either is 255, we still + * need to invalidate.) + */ + if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL + || oldflags != surface->flags + || (((oldalpha + 1) ^ (value + 1)) & 0x100)) + SDL_InvalidateMap(surface->map); + return(0); +} +int SDL_SetAlphaChannel(SDL_Surface *surface, Uint8 value) +{ + int row, col; + int offset; + Uint8 *buf; + + if ( (surface->format->Amask != 0xFF000000) && + (surface->format->Amask != 0x000000FF) ) { + SDL_SetError("Unsupported surface alpha mask format"); + return -1; + } + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + if ( surface->format->Amask == 0xFF000000 ) { + offset = 3; + } else { + offset = 0; + } +#else + if ( surface->format->Amask == 0xFF000000 ) { + offset = 0; + } else { + offset = 3; + } +#endif /* Byte ordering */ + + /* Quickly set the alpha channel of an RGBA or ARGB surface */ + if ( SDL_MUSTLOCK(surface) ) { + if ( SDL_LockSurface(surface) < 0 ) { + return -1; + } + } + row = surface->h; + while (row--) { + col = surface->w; + buf = (Uint8 *)surface->pixels + row * surface->pitch + offset; + while(col--) { + *buf = value; + buf += 4; + } + } + if ( SDL_MUSTLOCK(surface) ) { + SDL_UnlockSurface(surface); + } + return 0; +} + +/* + * A function to calculate the intersection of two rectangles: + * return true if the rectangles intersect, false otherwise + */ +static __inline__ +SDL_bool SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *intersection) +{ + int Amin, Amax, Bmin, Bmax; + + /* Horizontal intersection */ + Amin = A->x; + Amax = Amin + A->w; + Bmin = B->x; + Bmax = Bmin + B->w; + if(Bmin > Amin) + Amin = Bmin; + intersection->x = Amin; + if(Bmax < Amax) + Amax = Bmax; + intersection->w = Amax - Amin > 0 ? Amax - Amin : 0; + + /* Vertical intersection */ + Amin = A->y; + Amax = Amin + A->h; + Bmin = B->y; + Bmax = Bmin + B->h; + if(Bmin > Amin) + Amin = Bmin; + intersection->y = Amin; + if(Bmax < Amax) + Amax = Bmax; + intersection->h = Amax - Amin > 0 ? Amax - Amin : 0; + + return (intersection->w && intersection->h); +} +/* + * Set the clipping rectangle for a blittable surface + */ +SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect) +{ + SDL_Rect full_rect; + + /* Don't do anything if there's no surface to act on */ + if ( ! surface ) { + return SDL_FALSE; + } + + /* Set up the full surface rectangle */ + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = surface->w; + full_rect.h = surface->h; + + /* Set the clipping rectangle */ + if ( ! rect ) { + surface->clip_rect = full_rect; + return 1; + } + return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect); +} +void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect) +{ + if ( surface && rect ) { + *rect = surface->clip_rect; + } +} +/* + * Set up a blit between two surfaces -- split into three parts: + * The upper part, SDL_UpperBlit(), performs clipping and rectangle + * verification. The lower part is a pointer to a low level + * accelerated blitting function. + * + * These parts are separated out and each used internally by this + * library in the optimimum places. They are exported so that if + * you know exactly what you are doing, you can optimize your code + * by calling the one(s) you need. + */ +int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_blit do_blit; + SDL_Rect hw_srcrect; + SDL_Rect hw_dstrect; + + /* Check to make sure the blit mapping is valid */ + if ( (src->map->dst != dst) || + (src->map->dst->format_version != src->map->format_version) ) { + if ( SDL_MapSurface(src, dst) < 0 ) { + return(-1); + } + } + + /* Figure out which blitter to use */ + if ( (src->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + if ( src == SDL_VideoSurface ) { + hw_srcrect = *srcrect; + hw_srcrect.x += current_video->offset_x; + hw_srcrect.y += current_video->offset_y; + srcrect = &hw_srcrect; + } + if ( dst == SDL_VideoSurface ) { + hw_dstrect = *dstrect; + hw_dstrect.x += current_video->offset_x; + hw_dstrect.y += current_video->offset_y; + dstrect = &hw_dstrect; + } + do_blit = src->map->hw_blit; + } else { + do_blit = src->map->sw_blit; + } + return(do_blit(src, srcrect, dst, dstrect)); +} + + +int SDL_UpperBlit (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_Rect fulldst; + int srcx, srcy, w, h; + + /* Make sure the surfaces aren't locked */ + if ( ! src || ! dst ) { + SDL_SetError("SDL_UpperBlit: passed a NULL surface"); + return(-1); + } + if ( src->locked || dst->locked ) { + SDL_SetError("Surfaces must not be locked during blit"); + return(-1); + } + + /* If the destination rectangle is NULL, use the entire dest surface */ + if ( dstrect == NULL ) { + fulldst.x = fulldst.y = 0; + dstrect = &fulldst; + } + + /* clip the source rectangle to the source surface */ + if(srcrect) { + int maxw, maxh; + + srcx = srcrect->x; + w = srcrect->w; + if(srcx < 0) { + w += srcx; + dstrect->x -= srcx; + srcx = 0; + } + maxw = src->w - srcx; + if(maxw < w) + w = maxw; + + srcy = srcrect->y; + h = srcrect->h; + if(srcy < 0) { + h += srcy; + dstrect->y -= srcy; + srcy = 0; + } + maxh = src->h - srcy; + if(maxh < h) + h = maxh; + + } else { + srcx = srcy = 0; + w = src->w; + h = src->h; + } + + /* clip the destination rectangle against the clip rectangle */ + { + SDL_Rect *clip = &dst->clip_rect; + int dx, dy; + + dx = clip->x - dstrect->x; + if(dx > 0) { + w -= dx; + dstrect->x += dx; + srcx += dx; + } + dx = dstrect->x + w - clip->x - clip->w; + if(dx > 0) + w -= dx; + + dy = clip->y - dstrect->y; + if(dy > 0) { + h -= dy; + dstrect->y += dy; + srcy += dy; + } + dy = dstrect->y + h - clip->y - clip->h; + if(dy > 0) + h -= dy; + } + + if(w > 0 && h > 0) { + SDL_Rect sr; + sr.x = srcx; + sr.y = srcy; + sr.w = dstrect->w = w; + sr.h = dstrect->h = h; + return SDL_LowerBlit(src, &sr, dst, dstrect); + } + dstrect->w = dstrect->h = 0; + return 0; +} + +static int SDL_FillRect1(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + /* FIXME: We have to worry about packing order.. *sigh* */ + SDL_SetError("1-bpp rect fill not yet implemented"); + return -1; +} + +static int SDL_FillRect4(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + /* FIXME: We have to worry about packing order.. *sigh* */ + SDL_SetError("4-bpp rect fill not yet implemented"); + return -1; +} + +/* + * This function performs a fast fill of the given rectangle with 'color' + */ +int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int x, y; + Uint8 *row; + + /* This function doesn't work on surfaces < 8 bpp */ + if ( dst->format->BitsPerPixel < 8 ) { + switch(dst->format->BitsPerPixel) { + case 1: + return SDL_FillRect1(dst, dstrect, color); + break; + case 4: + return SDL_FillRect4(dst, dstrect, color); + break; + default: + SDL_SetError("Fill rect on unsupported surface format"); + return(-1); + break; + } + } + + /* If 'dstrect' == NULL, then fill the whole surface */ + if ( dstrect ) { + /* Perform clipping */ + if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) { + return(0); + } + } else { + dstrect = &dst->clip_rect; + } + + /* Check for hardware acceleration */ + if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && + video->info.blit_fill ) { + SDL_Rect hw_rect; + if ( dst == SDL_VideoSurface ) { + hw_rect = *dstrect; + hw_rect.x += current_video->offset_x; + hw_rect.y += current_video->offset_y; + dstrect = &hw_rect; + } + return(video->FillHWRect(this, dst, dstrect, color)); + } + + /* Perform software fill */ + if ( SDL_LockSurface(dst) != 0 ) { + return(-1); + } + row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+ + dstrect->x*dst->format->BytesPerPixel; + if ( dst->format->palette || (color == 0) ) { + x = dstrect->w*dst->format->BytesPerPixel; + if ( !color && !((uintptr_t)row&3) && !(x&3) && !(dst->pitch&3) ) { + int n = x >> 2; + for ( y=dstrect->h; y; --y ) { + SDL_memset4(row, 0, n); + row += dst->pitch; + } + } else { +#ifdef __powerpc__ + /* + * SDL_memset() on PPC (both glibc and codewarrior) uses + * the dcbz (Data Cache Block Zero) instruction, which + * causes an alignment exception if the destination is + * uncachable, so only use it on software surfaces + */ + if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { + if(dstrect->w >= 8) { + /* + * 64-bit stores are probably most + * efficient to uncached video memory + */ + double fill; + SDL_memset(&fill, color, (sizeof fill)); + for(y = dstrect->h; y; y--) { + Uint8 *d = row; + unsigned n = x; + unsigned nn; + Uint8 c = color; + double f = fill; + while((unsigned long)d + & (sizeof(double) - 1)) { + *d++ = c; + n--; + } + nn = n / (sizeof(double) * 4); + while(nn) { + ((double *)d)[0] = f; + ((double *)d)[1] = f; + ((double *)d)[2] = f; + ((double *)d)[3] = f; + d += 4*sizeof(double); + nn--; + } + n &= ~(sizeof(double) * 4 - 1); + nn = n / sizeof(double); + while(nn) { + *(double *)d = f; + d += sizeof(double); + nn--; + } + n &= ~(sizeof(double) - 1); + while(n) { + *d++ = c; + n--; + } + row += dst->pitch; + } + } else { + /* narrow boxes */ + for(y = dstrect->h; y; y--) { + Uint8 *d = row; + Uint8 c = color; + int n = x; + while(n) { + *d++ = c; + n--; + } + row += dst->pitch; + } + } + } else +#endif /* __powerpc__ */ + { + for(y = dstrect->h; y; y--) { + SDL_memset(row, color, x); + row += dst->pitch; + } + } + } + } else { + switch (dst->format->BytesPerPixel) { + case 2: + for ( y=dstrect->h; y; --y ) { + Uint16 *pixels = (Uint16 *)row; + Uint16 c = (Uint16)color; + Uint32 cc = (Uint32)c << 16 | c; + int n = dstrect->w; + if((uintptr_t)pixels & 3) { + *pixels++ = c; + n--; + } + if(n >> 1) + SDL_memset4(pixels, cc, n >> 1); + if(n & 1) + pixels[n - 1] = c; + row += dst->pitch; + } + break; + + case 3: + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + color <<= 8; + #endif + for ( y=dstrect->h; y; --y ) { + Uint8 *pixels = row; + for ( x=dstrect->w; x; --x ) { + SDL_memcpy(pixels, &color, 3); + pixels += 3; + } + row += dst->pitch; + } + break; + + case 4: + for(y = dstrect->h; y; --y) { + SDL_memset4(row, color, dstrect->w); + row += dst->pitch; + } + break; + } + } + SDL_UnlockSurface(dst); + + /* We're done! */ + return(0); +} + +/* + * Lock a surface to directly access the pixels + */ +int SDL_LockSurface (SDL_Surface *surface) +{ + if ( ! surface->locked ) { + /* Perform the lock */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, surface) < 0 ) { + return(-1); + } + } + if ( surface->flags & SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + surface->flags |= SDL_RLEACCEL; /* save accel'd state */ + } + /* This needs to be done here in case pixels changes value */ + surface->pixels = (Uint8 *)surface->pixels + surface->offset; + } + + /* Increment the surface lock count, for recursive locks */ + ++surface->locked; + + /* Ready to go.. */ + return(0); +} +/* + * Unlock a previously locked surface + */ +void SDL_UnlockSurface (SDL_Surface *surface) +{ + /* Only perform an unlock if we are locked */ + if ( ! surface->locked || (--surface->locked > 0) ) { + return; + } + + /* Perform the unlock */ + surface->pixels = (Uint8 *)surface->pixels - surface->offset; + + /* Unlock hardware or accelerated surfaces */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, surface); + } else { + /* Update RLE encoded surface with new data */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + surface->flags &= ~SDL_RLEACCEL; /* stop lying */ + SDL_RLESurface(surface); + } + } +} + +/* + * Convert a surface into the specified pixel format. + */ +SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface, + SDL_PixelFormat *format, Uint32 flags) +{ + SDL_Surface *convert; + Uint32 colorkey = 0; + Uint8 alpha = 0; + Uint32 surface_flags; + SDL_Rect bounds; + + /* Check for empty destination palette! (results in empty image) */ + if ( format->palette != NULL ) { + int i; + for ( i=0; ipalette->ncolors; ++i ) { + if ( (format->palette->colors[i].r != 0) || + (format->palette->colors[i].g != 0) || + (format->palette->colors[i].b != 0) ) + break; + } + if ( i == format->palette->ncolors ) { + SDL_SetError("Empty destination palette"); + return(NULL); + } + } + + /* Only create hw surfaces with alpha channel if hw alpha blits + are supported */ + if(format->Amask != 0 && (flags & SDL_HWSURFACE)) { + const SDL_VideoInfo *vi = SDL_GetVideoInfo(); + if(!vi || !vi->blit_hw_A) + flags &= ~SDL_HWSURFACE; + } + + /* Create a new surface with the desired format */ + convert = SDL_CreateRGBSurface(flags, + surface->w, surface->h, format->BitsPerPixel, + format->Rmask, format->Gmask, format->Bmask, format->Amask); + if ( convert == NULL ) { + return(NULL); + } + + /* Copy the palette if any */ + if ( format->palette && convert->format->palette ) { + SDL_memcpy(convert->format->palette->colors, + format->palette->colors, + format->palette->ncolors*sizeof(SDL_Color)); + convert->format->palette->ncolors = format->palette->ncolors; + } + + /* Save the original surface color key and alpha */ + surface_flags = surface->flags; + if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + /* Convert colourkeyed surfaces to RGBA if requested */ + if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY + && format->Amask) { + surface_flags &= ~SDL_SRCCOLORKEY; + } else { + colorkey = surface->format->colorkey; + SDL_SetColorKey(surface, 0, 0); + } + } + if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + /* Copy over the alpha channel to RGBA if requested */ + if ( format->Amask ) { + surface->flags &= ~SDL_SRCALPHA; + } else { + alpha = surface->format->alpha; + SDL_SetAlpha(surface, 0, 0); + } + } + + /* Copy over the image data */ + bounds.x = 0; + bounds.y = 0; + bounds.w = surface->w; + bounds.h = surface->h; + SDL_LowerBlit(surface, &bounds, convert, &bounds); + + /* Clean up the original surface, and update converted surface */ + if ( convert != NULL ) { + SDL_SetClipRect(convert, &surface->clip_rect); + } + if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK); + if ( convert != NULL ) { + Uint8 keyR, keyG, keyB; + + SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB); + SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK), + SDL_MapRGB(convert->format, keyR, keyG, keyB)); + } + SDL_SetColorKey(surface, cflags, colorkey); + } + if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK); + if ( convert != NULL ) { + SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK), + alpha); + } + if ( format->Amask ) { + surface->flags |= SDL_SRCALPHA; + } else { + SDL_SetAlpha(surface, aflags, alpha); + } + } + + /* We're ready to go! */ + return(convert); +} + +/* + * Free a surface created by the above function. + */ +void SDL_FreeSurface (SDL_Surface *surface) +{ + /* Free anything that's not NULL, and not the screen surface */ + if ((surface == NULL) || + (current_video && + ((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) { + return; + } + if ( --surface->refcount > 0 ) { + return; + } + while ( surface->locked > 0 ) { + SDL_UnlockSurface(surface); + } + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 0); + } + if ( surface->format ) { + SDL_FreeFormat(surface->format); + surface->format = NULL; + } + if ( surface->map != NULL ) { + SDL_FreeBlitMap(surface->map); + surface->map = NULL; + } + if ( surface->hwdata ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->FreeHWSurface(this, surface); + } + if ( surface->pixels && + ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) { + SDL_free(surface->pixels); + } + SDL_free(surface); +#ifdef CHECK_LEAKS + --surfaces_allocated; +#endif +} diff --git a/apps/plugins/sdl/src/video/SDL_sysvideo.h b/apps/plugins/sdl/src/video/SDL_sysvideo.h new file mode 100644 index 0000000000..31badaeaa0 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_sysvideo.h @@ -0,0 +1,427 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_sysvideo_h +#define _SDL_sysvideo_h + +#include "SDL_mouse.h" +#define SDL_PROTOTYPES_ONLY +#include "SDL_syswm.h" +#undef SDL_PROTOTYPES_ONLY + +/* This file prototypes the video driver implementation. + This is designed to be easily converted to C++ in the future. + */ + +#if SDL_VIDEO_OPENGL +#include "SDL_opengl.h" +#endif /* SDL_VIDEO_OPENGL */ + +/* The SDL video driver */ +typedef struct SDL_VideoDevice SDL_VideoDevice; + +/* Define the SDL video driver structure */ +#define _THIS SDL_VideoDevice *_this +#ifndef _STATUS +#define _STATUS SDL_status *status +#endif +struct SDL_VideoDevice { + /* * * */ + /* The name of this video driver */ + const char *name; + + /* * * */ + /* Initialization/Query functions */ + + /* Initialize the native video subsystem, filling 'vformat' with the + "best" display pixel format, returning 0 or -1 if there's an error. + */ + int (*VideoInit)(_THIS, SDL_PixelFormat *vformat); + + /* List the available video modes for the given pixel format, sorted + from largest to smallest. + */ + SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags); + + /* Set the requested video mode, returning a surface which will be + set to the SDL_VideoSurface. The width and height will already + be verified by ListModes(), and the video subsystem is free to + set the mode to a supported bit depth different from the one + specified -- the desired bpp will be emulated with a shadow + surface if necessary. If a new mode is returned, this function + should take care of cleaning up the current mode. + */ + SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags); + + /* Toggle the fullscreen mode */ + int (*ToggleFullScreen)(_THIS, int on); + + /* This is called after the video mode has been set, to get the + initial mouse state. It should queue events as necessary to + properly represent the current mouse focus and position. + */ + void (*UpdateMouse)(_THIS); + + /* Create a YUV video surface (possibly overlay) of the given + format. The hardware should be able to perform at least 2x + scaling on display. + */ + SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height, + Uint32 format, SDL_Surface *display); + + /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) } + of the physical palette to those in 'colors'. If the device is + using a software palette (SDL_HWPALETTE not set), then the + changes are reflected in the logical palette of the screen + as well. + The return value is 1 if all entries could be set properly + or 0 otherwise. + */ + int (*SetColors)(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); + + /* This pointer should exist in the native video subsystem and should + point to an appropriate update function for the current video mode + */ + void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects); + + /* Reverse the effects VideoInit() -- called if VideoInit() fails + or if the application is shutting down the video subsystem. + */ + void (*VideoQuit)(_THIS); + + /* * * */ + /* Hardware acceleration functions */ + + /* Information about the video hardware */ + SDL_VideoInfo info; + + /* The pixel format used when SDL_CreateRGBSurface creates SDL_HWSURFACEs with alpha */ + SDL_PixelFormat* displayformatalphapixel; + + /* Allocates a surface in video memory */ + int (*AllocHWSurface)(_THIS, SDL_Surface *surface); + + /* Sets the hardware accelerated blit function, if any, based + on the current flags of the surface (colorkey, alpha, etc.) + */ + int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst); + + /* Fills a surface rectangle with the given color */ + int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); + + /* Sets video mem colorkey and accelerated blit function */ + int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key); + + /* Sets per surface hardware alpha value */ + int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value); + + /* Returns a readable/writable surface */ + int (*LockHWSurface)(_THIS, SDL_Surface *surface); + void (*UnlockHWSurface)(_THIS, SDL_Surface *surface); + + /* Performs hardware flipping */ + int (*FlipHWSurface)(_THIS, SDL_Surface *surface); + + /* Frees a previously allocated video surface */ + void (*FreeHWSurface)(_THIS, SDL_Surface *surface); + + /* * * */ + /* Gamma support */ + + Uint16 *gamma; + + /* Set the gamma correction directly (emulated with gamma ramps) */ + int (*SetGamma)(_THIS, float red, float green, float blue); + + /* Get the gamma correction directly (emulated with gamma ramps) */ + int (*GetGamma)(_THIS, float *red, float *green, float *blue); + + /* Set the gamma ramp */ + int (*SetGammaRamp)(_THIS, Uint16 *ramp); + + /* Get the gamma ramp */ + int (*GetGammaRamp)(_THIS, Uint16 *ramp); + + /* * * */ + /* OpenGL support */ + + /* Sets the dll to use for OpenGL and loads it */ + int (*GL_LoadLibrary)(_THIS, const char *path); + + /* Retrieves the address of a function in the gl library */ + void* (*GL_GetProcAddress)(_THIS, const char *proc); + + /* Get attribute information from the windowing system. */ + int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int* value); + + /* Make the context associated with this driver current */ + int (*GL_MakeCurrent)(_THIS); + + /* Swap the current buffers in double buffer mode. */ + void (*GL_SwapBuffers)(_THIS); + + /* OpenGL functions for SDL_OPENGLBLIT */ +#if SDL_VIDEO_OPENGL +#if !defined(__WIN32__) +#define WINAPI +#endif +#define SDL_PROC(ret,func,params) ret (WINAPI *func) params; +#include "SDL_glfuncs.h" +#undef SDL_PROC + + /* Texture id */ + GLuint texture; +#endif + int is_32bit; + + /* * * */ + /* Window manager functions */ + + /* Set the title and icon text */ + void (*SetCaption)(_THIS, const char *title, const char *icon); + + /* Set the window icon image */ + void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask); + + /* Iconify the window. + This function returns 1 if there is a window manager and the + window was actually iconified, it returns 0 otherwise. + */ + int (*IconifyWindow)(_THIS); + + /* Grab or ungrab keyboard and mouse input */ + SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode); + + /* Get some platform dependent window information */ + int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info); + + /* * * */ + /* Cursor manager functions */ + + /* Free a window manager cursor + This function can be NULL if CreateWMCursor is also NULL. + */ + void (*FreeWMCursor)(_THIS, WMcursor *cursor); + + /* If not NULL, create a black/white window manager cursor */ + WMcursor *(*CreateWMCursor)(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + + /* Show the specified cursor, or hide if cursor is NULL */ + int (*ShowWMCursor)(_THIS, WMcursor *cursor); + + /* Warp the window manager cursor to (x,y) + If NULL, a mouse motion event is posted internally. + */ + void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y); + + /* If not NULL, this is called when a mouse motion event occurs */ + void (*MoveWMCursor)(_THIS, int x, int y); + + /* Determine whether the mouse should be in relative mode or not. + This function is called when the input grab state or cursor + visibility state changes. + If the cursor is not visible, and the input is grabbed, the + driver can place the mouse in relative mode, which may result + in higher accuracy sampling of the pointer motion. + */ + void (*CheckMouseMode)(_THIS); + + /* * * */ + /* Event manager functions */ + + /* Initialize keyboard mapping for this driver */ + void (*InitOSKeymap)(_THIS); + + /* Handle any queued OS events */ + void (*PumpEvents)(_THIS); + + /* * * */ + /* Data common to all drivers */ + SDL_Surface *screen; + SDL_Surface *shadow; + SDL_Surface *visible; + SDL_Palette *physpal; /* physical palette, if != logical palette */ + SDL_Color *gammacols; /* gamma-corrected colours, or NULL */ + char *wm_title; + char *wm_icon; + int offset_x; + int offset_y; + SDL_GrabMode input_grab; + + /* Driver information flags */ + int handles_any_size; /* Driver handles any size video mode */ + + /* * * */ + /* Data used by the GL drivers */ + struct { + int red_size; + int green_size; + int blue_size; + int alpha_size; + int depth_size; + int buffer_size; + int stencil_size; + int double_buffer; + int accum_red_size; + int accum_green_size; + int accum_blue_size; + int accum_alpha_size; + int stereo; + int multisamplebuffers; + int multisamplesamples; + int accelerated; + int swap_control; + int driver_loaded; + char driver_path[256]; + void* dll_handle; + } gl_config; + + /* * * */ + /* Data private to this driver */ + struct SDL_PrivateVideoData *hidden; + struct SDL_PrivateGLData *gl_data; + + /* * * */ + /* The function used to dispose of this structure */ + void (*free)(_THIS); +}; +#undef _THIS + +typedef struct VideoBootStrap { + const char *name; + const char *desc; + int (*available)(void); + SDL_VideoDevice *(*create)(int devindex); +} VideoBootStrap; + +#if SDL_VIDEO_DRIVER_QUARTZ +extern VideoBootStrap QZ_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_X11 +extern VideoBootStrap X11_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DGA +extern VideoBootStrap DGA_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_NANOX +extern VideoBootStrap NX_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_IPOD +extern VideoBootStrap iPod_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_QTOPIA +extern VideoBootStrap Qtopia_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_WSCONS +extern VideoBootStrap WSCONS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_FBCON +extern VideoBootStrap FBCON_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DIRECTFB +extern VideoBootStrap DirectFB_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PS2GS +extern VideoBootStrap PS2GS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PS3 +extern VideoBootStrap PS3_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_GGI +extern VideoBootStrap GGI_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_VGL +extern VideoBootStrap VGL_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_SVGALIB +extern VideoBootStrap SVGALIB_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_GAPI +extern VideoBootStrap GAPI_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_WINDIB +extern VideoBootStrap WINDIB_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DDRAW +extern VideoBootStrap DIRECTX_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_BWINDOW +extern VideoBootStrap BWINDOW_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_TOOLBOX +extern VideoBootStrap TOOLBOX_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DRAWSPROCKET +extern VideoBootStrap DSp_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PHOTON +extern VideoBootStrap ph_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_EPOC +extern VideoBootStrap EPOC_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_XBIOS +extern VideoBootStrap XBIOS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_GEM +extern VideoBootStrap GEM_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_PICOGUI +extern VideoBootStrap PG_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DC +extern VideoBootStrap DC_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_NDS +extern VideoBootStrap NDS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_RISCOS +extern VideoBootStrap RISCOS_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_OS2FS +extern VideoBootStrap OS2FSLib_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_AALIB +extern VideoBootStrap AALIB_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_CACA +extern VideoBootStrap CACA_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_DUMMY +extern VideoBootStrap DUMMY_bootstrap; +#endif +#if SDL_VIDEO_DRIVER_ROCKBOX +extern VideoBootStrap ROCKBOX_bootstrap; +#endif + +/* This is the current video device */ +extern SDL_VideoDevice *current_video; + +#define SDL_VideoSurface (current_video->screen) +#define SDL_ShadowSurface (current_video->shadow) +#define SDL_PublicSurface (current_video->visible) + +#endif /* _SDL_sysvideo_h */ diff --git a/apps/plugins/sdl/src/video/SDL_video.c b/apps/plugins/sdl/src/video/SDL_video.c new file mode 100644 index 0000000000..2648d1fb3c --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_video.c @@ -0,0 +1,1978 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* The high-level video driver subsystem */ + +#include "SDL.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_cursor_c.h" +#include "../events/SDL_sysevents.h" +#include "../events/SDL_events_c.h" + +/* Available video drivers */ +static VideoBootStrap *bootstrap[] = { +#if SDL_VIDEO_DRIVER_QUARTZ + &QZ_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_X11 + &X11_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DGA + &DGA_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_NANOX + &NX_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_IPOD + &iPod_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_QTOPIA + &Qtopia_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_WSCONS + &WSCONS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_FBCON + &FBCON_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DIRECTFB + &DirectFB_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PS2GS + &PS2GS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PS3 + &PS3_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_GGI + &GGI_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_VGL + &VGL_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_SVGALIB + &SVGALIB_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_GAPI + &GAPI_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_WINDIB + &WINDIB_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DDRAW + &DIRECTX_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_BWINDOW + &BWINDOW_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_TOOLBOX + &TOOLBOX_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DRAWSPROCKET + &DSp_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PHOTON + &ph_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_EPOC + &EPOC_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_XBIOS + &XBIOS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_GEM + &GEM_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_PICOGUI + &PG_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DC + &DC_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_NDS + &NDS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_RISCOS + &RISCOS_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_OS2FS + &OS2FSLib_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_AALIB + &AALIB_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_CACA + &CACA_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_DUMMY + &DUMMY_bootstrap, +#endif +#if SDL_VIDEO_DRIVER_ROCKBOX + &ROCKBOX_bootstrap, +#endif + NULL +}; + +SDL_VideoDevice *current_video = NULL; + +/* Various local functions */ +int SDL_VideoInit(const char *driver_name, Uint32 flags); +void SDL_VideoQuit(void); +void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects); + +static SDL_GrabMode SDL_WM_GrabInputOff(void); +#if SDL_VIDEO_OPENGL +static int lock_count = 0; +#endif + + +/* + * Initialize the video and event subsystems -- determine native pixel format + */ +int SDL_VideoInit (const char *driver_name, Uint32 flags) +{ + SDL_VideoDevice *video; + int index; + int i; + SDL_PixelFormat vformat; + Uint32 video_flags; + + /* Toggle the event thread flags, based on OS requirements */ +#if defined(MUST_THREAD_EVENTS) + flags |= SDL_INIT_EVENTTHREAD; +#elif defined(CANT_THREAD_EVENTS) + if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { + SDL_SetError("OS doesn't support threaded events"); + return(-1); + } +#endif + + /* Check to make sure we don't overwrite 'current_video' */ + if ( current_video != NULL ) { + SDL_VideoQuit(); + } + + /* Select the proper video driver */ + index = 0; + video = NULL; + if ( driver_name != NULL ) { +#if 0 /* This will be replaced with a better driver selection API */ + if ( SDL_strrchr(driver_name, ':') != NULL ) { + index = atoi(SDL_strrchr(driver_name, ':')+1); + } +#endif + for ( i=0; bootstrap[i]; ++i ) { + if ( SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) { + if ( bootstrap[i]->available() ) { + video = bootstrap[i]->create(index); + break; + } + } + } + } else { + for ( i=0; bootstrap[i]; ++i ) { + if ( bootstrap[i]->available() ) { + video = bootstrap[i]->create(index); + if ( video != NULL ) { + break; + } + } + } + } + if ( video == NULL ) { + SDL_SetError("No available video device"); + return(-1); + } + current_video = video; + current_video->name = bootstrap[i]->name; + + /* Do some basic variable initialization */ + video->screen = NULL; + video->shadow = NULL; + video->visible = NULL; + video->physpal = NULL; + video->gammacols = NULL; + video->gamma = NULL; + video->wm_title = NULL; + video->wm_icon = NULL; + video->offset_x = 0; + video->offset_y = 0; + SDL_memset(&video->info, 0, (sizeof video->info)); + + video->displayformatalphapixel = NULL; + + /* Set some very sane GL defaults */ + video->gl_config.driver_loaded = 0; + video->gl_config.dll_handle = NULL; + video->gl_config.red_size = 3; + video->gl_config.green_size = 3; + video->gl_config.blue_size = 2; + video->gl_config.alpha_size = 0; + video->gl_config.buffer_size = 0; + video->gl_config.depth_size = 16; + video->gl_config.stencil_size = 0; + video->gl_config.double_buffer = 1; + video->gl_config.accum_red_size = 0; + video->gl_config.accum_green_size = 0; + video->gl_config.accum_blue_size = 0; + video->gl_config.accum_alpha_size = 0; + video->gl_config.stereo = 0; + video->gl_config.multisamplebuffers = 0; + video->gl_config.multisamplesamples = 0; + video->gl_config.accelerated = -1; /* not known, don't set */ + video->gl_config.swap_control = -1; /* not known, don't set */ + + /* Initialize the video subsystem */ + SDL_memset(&vformat, 0, sizeof(vformat)); + if ( video->VideoInit(video, &vformat) < 0 ) { + SDL_VideoQuit(); + return(-1); + } + + /* Create a zero sized video surface of the appropriate format */ + video_flags = SDL_SWSURFACE; + SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0, + vformat.BitsPerPixel, + vformat.Rmask, vformat.Gmask, vformat.Bmask, 0); + if ( SDL_VideoSurface == NULL ) { + SDL_VideoQuit(); + return(-1); + } + SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */ + +#if 0 /* Don't change the current palette - may be used by other programs. + * The application can't do anything with the display surface until + * a video mode has been set anyway. :) + */ + /* If we have a palettized surface, create a default palette */ + if ( SDL_VideoSurface->format->palette ) { + SDL_PixelFormat *vf = SDL_VideoSurface->format; + SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); + video->SetColors(video, + 0, vf->palette->ncolors, vf->palette->colors); + } +#endif + video->info.vfmt = SDL_VideoSurface->format; + + /* Start the event loop */ + if ( SDL_StartEventLoop(flags) < 0 ) { + SDL_VideoQuit(); + return(-1); + } + SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD); + + /* We're ready to go! */ + return(0); +} + +char *SDL_VideoDriverName(char *namebuf, int maxlen) +{ + if ( current_video != NULL ) { + SDL_strlcpy(namebuf, current_video->name, maxlen); + return(namebuf); + } + return(NULL); +} + +/* + * Get the current display surface + */ +SDL_Surface *SDL_GetVideoSurface(void) +{ + SDL_Surface *visible; + + visible = NULL; + if ( current_video ) { + visible = current_video->visible; + } + return(visible); +} + +/* + * Get the current information about the video hardware + */ +const SDL_VideoInfo *SDL_GetVideoInfo(void) +{ + const SDL_VideoInfo *info; + + info = NULL; + if ( current_video ) { + info = ¤t_video->info; + } + return(info); +} + +/* + * Return a pointer to an array of available screen dimensions for the + * given format, sorted largest to smallest. Returns NULL if there are + * no dimensions available for a particular format, or (SDL_Rect **)-1 + * if any dimension is okay for the given format. If 'format' is NULL, + * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt + */ +SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect **modes; + + modes = NULL; + if ( SDL_VideoSurface ) { + if ( format == NULL ) { + format = SDL_VideoSurface->format; + } + modes = video->ListModes(this, format, flags); + } + return(modes); +} + +/* + * Check to see if a particular video mode is supported. + * It returns 0 if the requested mode is not supported under any bit depth, + * or returns the bits-per-pixel of the closest available mode with the + * given width and height. If this bits-per-pixel is different from the + * one used when setting the video mode, SDL_SetVideoMode() will succeed, + * but will emulate the requested bits-per-pixel with a shadow surface. + */ +static Uint8 SDL_closest_depths[4][8] = { + /* 8 bit closest depth ordering */ + { 0, 8, 16, 15, 32, 24, 0, 0 }, + /* 15,16 bit closest depth ordering */ + { 0, 16, 15, 32, 24, 8, 0, 0 }, + /* 24 bit closest depth ordering */ + { 0, 24, 32, 16, 15, 8, 0, 0 }, + /* 32 bit closest depth ordering */ + { 0, 32, 16, 15, 24, 8, 0, 0 } +}; + + +#ifdef __MACOS__ /* MPW optimization bug? */ +#define NEGATIVE_ONE 0xFFFFFFFF +#else +#define NEGATIVE_ONE -1 +#endif + +int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) +{ + int table, b, i; + int supported; + SDL_PixelFormat format; + SDL_Rect **sizes; + + /* Currently 1 and 4 bpp are not supported */ + if ( bpp < 8 || bpp > 32 ) { + return(0); + } + if ( (width <= 0) || (height <= 0) ) { + return(0); + } + + /* Search through the list valid of modes */ + SDL_memset(&format, 0, sizeof(format)); + supported = 0; + table = ((bpp+7)/8)-1; + SDL_closest_depths[table][0] = bpp; + SDL_closest_depths[table][7] = 0; + for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { + format.BitsPerPixel = SDL_closest_depths[table][b]; + sizes = SDL_ListModes(&format, flags); + if ( sizes == (SDL_Rect **)0 ) { + /* No sizes supported at this bit-depth */ + continue; + } else + if (sizes == (SDL_Rect **)NEGATIVE_ONE) { + /* Any size supported at this bit-depth */ + supported = 1; + continue; + } else if (current_video->handles_any_size) { + /* Driver can center a smaller surface to simulate fullscreen */ + for ( i=0; sizes[i]; ++i ) { + if ((sizes[i]->w >= width) && (sizes[i]->h >= height)) { + supported = 1; /* this mode can fit the centered window. */ + break; + } + } + } else + for ( i=0; sizes[i]; ++i ) { + if ((sizes[i]->w == width) && (sizes[i]->h == height)) { + supported = 1; + break; + } + } + } + if ( supported ) { + --b; + return(SDL_closest_depths[table][b]); + } else { + return(0); + } +} + +/* + * Get the closest non-emulated video mode to the one requested + */ +static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags) +{ + int table, b, i; + int supported; + int native_bpp; + SDL_PixelFormat format; + SDL_Rect **sizes; + + /* Check parameters */ + if ( *BitsPerPixel < 8 || *BitsPerPixel > 32 ) { + SDL_SetError("Invalid bits per pixel (range is {8...32})"); + return(0); + } + if ((*w <= 0) || (*h <= 0)) { + SDL_SetError("Invalid width or height"); + return(0); + } + + /* Try the original video mode, get the closest depth */ + native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags); + if ( native_bpp == *BitsPerPixel ) { + return(1); + } + if ( native_bpp > 0 ) { + *BitsPerPixel = native_bpp; + return(1); + } + + /* No exact size match at any depth, look for closest match */ + SDL_memset(&format, 0, sizeof(format)); + supported = 0; + table = ((*BitsPerPixel+7)/8)-1; + SDL_closest_depths[table][0] = *BitsPerPixel; + SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel; + for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { + int best; + + format.BitsPerPixel = SDL_closest_depths[table][b]; + sizes = SDL_ListModes(&format, flags); + if ( sizes == (SDL_Rect **)0 ) { + /* No sizes supported at this bit-depth */ + continue; + } + best=0; + for ( i=0; sizes[i]; ++i ) { + /* Mode with both dimensions bigger or equal than asked ? */ + if ((sizes[i]->w >= *w) && (sizes[i]->h >= *h)) { + /* Mode with any dimension smaller or equal than current best ? */ + if ((sizes[i]->w <= sizes[best]->w) || (sizes[i]->h <= sizes[best]->h)) { + /* Now choose the mode that has less pixels */ + if ((sizes[i]->w * sizes[i]->h) <= (sizes[best]->w * sizes[best]->h)) { + best=i; + supported = 1; + } + } + } + } + if (supported) { + *w=sizes[best]->w; + *h=sizes[best]->h; + *BitsPerPixel = SDL_closest_depths[table][b]; + } + } + if ( ! supported ) { + SDL_SetError("No video mode large enough for %dx%d", *w, *h); + } + return(supported); +} + +/* This should probably go somewhere else -- like SDL_surface.c */ +static void SDL_ClearSurface(SDL_Surface *surface) +{ + Uint32 black; + + black = SDL_MapRGB(surface->format, 0, 0, 0); + SDL_FillRect(surface, NULL, black); + if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) { + SDL_Flip(surface); + SDL_FillRect(surface, NULL, black); + } + if (surface->flags&SDL_FULLSCREEN) { + SDL_Flip(surface); + } +} + +/* + * Create a shadow surface suitable for fooling the app. :-) + */ +static void SDL_CreateShadowSurface(int depth) +{ + Uint32 Rmask, Gmask, Bmask; + + /* Allocate the shadow surface */ + if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { + Rmask = (SDL_VideoSurface->format)->Rmask; + Gmask = (SDL_VideoSurface->format)->Gmask; + Bmask = (SDL_VideoSurface->format)->Bmask; + } else { + Rmask = Gmask = Bmask = 0; + } + SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, + SDL_VideoSurface->w, SDL_VideoSurface->h, + depth, Rmask, Gmask, Bmask, 0); + if ( SDL_ShadowSurface == NULL ) { + return; + } + + /* 8-bit shadow surfaces report that they have exclusive palette */ + if ( SDL_ShadowSurface->format->palette ) { + SDL_ShadowSurface->flags |= SDL_HWPALETTE; + if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { + SDL_memcpy(SDL_ShadowSurface->format->palette->colors, + SDL_VideoSurface->format->palette->colors, + SDL_VideoSurface->format->palette->ncolors* + sizeof(SDL_Color)); + } else { + SDL_DitherColors( + SDL_ShadowSurface->format->palette->colors, depth); + } + } + + /* If the video surface is resizable, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) { + SDL_ShadowSurface->flags |= SDL_RESIZABLE; + } + /* If the video surface has no frame, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) { + SDL_ShadowSurface->flags |= SDL_NOFRAME; + } + /* If the video surface is fullscreen, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { + SDL_ShadowSurface->flags |= SDL_FULLSCREEN; + } + /* If the video surface is flippable, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + SDL_ShadowSurface->flags |= SDL_DOUBLEBUF; + } + return; +} + +#ifdef __QNXNTO__ + #include +#endif /* __QNXNTO__ */ + +#ifdef WIN32 + extern int sysevents_mouse_pressed; +#endif + +/* + * Set the requested video mode, allocating a shadow buffer if necessary. + */ +SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) +{ + SDL_VideoDevice *video, *this; + SDL_Surface *prev_mode, *mode; + int video_w; + int video_h; + int video_bpp; + int is_opengl; + SDL_GrabMode saved_grab; + + #ifdef WIN32 + sysevents_mouse_pressed = 0; + #endif + + /* Start up the video driver, if necessary.. + WARNING: This is the only function protected this way! + */ + if ( ! current_video ) { + if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { + return(NULL); + } + } + this = video = current_video; + + /* Default to the current width and height */ + if ( width == 0 ) { + width = video->info.current_w; + } + if ( height == 0 ) { + height = video->info.current_h; + } + /* Default to the current video bpp */ + if ( bpp == 0 ) { + flags |= SDL_ANYFORMAT; + bpp = SDL_VideoSurface->format->BitsPerPixel; + } + + /* Get a good video mode, the closest one possible */ + video_w = width; + video_h = height; + video_bpp = bpp; + if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) { + return(NULL); + } + + /* Check the requested flags */ + /* There's no palette in > 8 bits-per-pixel mode */ + if ( video_bpp > 8 ) { + flags &= ~SDL_HWPALETTE; + } +#if 0 + if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) { + /* There's no windowed double-buffering */ + flags &= ~SDL_DOUBLEBUF; + } +#endif + if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + /* Use hardware surfaces when double-buffering */ + flags |= SDL_HWSURFACE; + } + + is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL ); + if ( is_opengl ) { + /* These flags are for 2D video modes only */ + flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF); + } + /* Reset the keyboard here so event callbacks can run */ + SDL_ResetKeyboard(); + SDL_ResetMouse(); + SDL_SetMouseRange(width, height); + SDL_cursorstate &= ~CURSOR_USINGSW; + + /* Clean up any previous video mode */ + if ( SDL_PublicSurface != NULL ) { + SDL_PublicSurface = NULL; + } + if ( SDL_ShadowSurface != NULL ) { + SDL_Surface *ready_to_go; + ready_to_go = SDL_ShadowSurface; + SDL_ShadowSurface = NULL; + SDL_FreeSurface(ready_to_go); + } + if ( video->physpal ) { + SDL_free(video->physpal->colors); + SDL_free(video->physpal); + video->physpal = NULL; + } + if( video->gammacols) { + SDL_free(video->gammacols); + video->gammacols = NULL; + } + /* Save the previous grab state and turn off grab for mode switch */ + saved_grab = SDL_WM_GrabInputOff(); + + /* Try to set the video mode, along with offset and clipping */ + prev_mode = SDL_VideoSurface; + SDL_LockCursor(); + SDL_VideoSurface = NULL; /* In case it's freed by driver */ + mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags); + + if ( mode ) { /* Prevent resize events from mode change */ + /* But not on OS/2 */ +#ifndef __OS2__ + SDL_PrivateResize(mode->w, mode->h); +#endif + + /* Sam - If we asked for OpenGL mode, and didn't get it, fail */ + if ( is_opengl && !(mode->flags & SDL_OPENGL) ) { + mode = NULL; + SDL_SetError("OpenGL not available"); + } + } + /* + * rcg11292000 + * If you try to set an SDL_OPENGL surface, and fail to find a + * matching visual, then the next call to SDL_SetVideoMode() + * will segfault, since we no longer point to a dummy surface, + * but rather NULL. + * Sam 11/29/00 + * WARNING, we need to make sure that the previous mode hasn't + * already been freed by the video driver. What do we do in + * that case? Should we call SDL_VideoInit() again? + */ + SDL_VideoSurface = (mode != NULL) ? mode : prev_mode; + if ( (mode != NULL) && (!is_opengl) ) { + /* Sanity check */ + if ( (mode->w < width) || (mode->h < height) ) { + SDL_SetError("Video mode smaller than requested"); + return(NULL); + } + + /* If we have a palettized surface, create a default palette */ + if ( mode->format->palette ) { + SDL_PixelFormat *vf = mode->format; + SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); + video->SetColors(this, 0, vf->palette->ncolors, + vf->palette->colors); + } + /* Clear the surface to black */ + video->offset_x = 0; + video->offset_y = 0; + mode->offset = 0; + SDL_SetClipRect(mode, NULL); + SDL_ClearSurface(mode); + /* Now adjust the offsets to match the desired mode */ + video->offset_x = (mode->w-width)/2; + video->offset_y = (mode->h-height)/2; + mode->offset = video->offset_y*mode->pitch + + video->offset_x*mode->format->BytesPerPixel; +#ifdef DEBUG_VIDEO + fprintf(stderr, + "Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n", + width, height, bpp, + mode->w, mode->h, mode->format->BitsPerPixel, mode->offset); +#endif + mode->w = width; + mode->h = height; + SDL_SetClipRect(mode, NULL); + } + SDL_ResetCursor(); + SDL_UnlockCursor(); + + /* If we failed setting a video mode, return NULL... (Uh Oh!) */ + if ( mode == NULL ) { + return(NULL); + } + + /* If there is no window manager, set the SDL_NOFRAME flag */ + if ( ! video->info.wm_available ) { + mode->flags |= SDL_NOFRAME; + } + + /* Reset the mouse cursor and grab for new video mode */ + SDL_SetCursor(NULL); + + if ( video->UpdateMouse ) { + video->UpdateMouse(this); + } + SDL_WM_GrabInput(saved_grab); + SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ + +#if SDL_VIDEO_OPENGL + /* Load GL symbols (before MakeCurrent, where we need glGetString). */ + if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) { + +#if defined(__QNXNTO__) && (_NTO_VERSION < 630) +#define __SDL_NOGETPROCADDR__ +#elif defined(__MINT__) +#define __SDL_NOGETPROCADDR__ +#endif +#ifdef __SDL_NOGETPROCADDR__ + #define SDL_PROC(ret,func,params) video->func=func; +#else + #define SDL_PROC(ret,func,params) \ + do { \ + video->func = SDL_GL_GetProcAddress(#func); \ + if ( ! video->func ) { \ + SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \ + return(NULL); \ + } \ + } while ( 0 ); + +#endif /* __SDL_NOGETPROCADDR__ */ + +#include "SDL_glfuncs.h" +#undef SDL_PROC + } +#endif /* SDL_VIDEO_OPENGL */ + + /* If we're running OpenGL, make the context current */ + if ( (video->screen->flags & SDL_OPENGL) && + video->GL_MakeCurrent ) { + if ( video->GL_MakeCurrent(this) < 0 ) { + return(NULL); + } + } + + /* Set up a fake SDL surface for OpenGL "blitting" */ + if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) { + /* Load GL functions for performing the texture updates */ +#if SDL_VIDEO_OPENGL + + /* Create a software surface for blitting */ +#ifdef GL_VERSION_1_2 + /* If the implementation either supports the packed pixels + extension, or implements the core OpenGL 1.2 API, it will + support the GL_UNSIGNED_SHORT_5_6_5 texture format. + */ + if ( (bpp == 16) && + (SDL_strstr((const char *)video->glGetString(GL_EXTENSIONS), "GL_EXT_packed_pixels") || + (SDL_atof((const char *)video->glGetString(GL_VERSION)) >= 1.2f)) + ) { + video->is_32bit = 0; + SDL_VideoSurface = SDL_CreateRGBSurface( + flags, + width, + height, + 16, + 31 << 11, + 63 << 5, + 31, + 0 + ); + } + else +#endif /* OpenGL 1.2 */ + { + video->is_32bit = 1; + SDL_VideoSurface = SDL_CreateRGBSurface( + flags, + width, + height, + 32, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000 +#else + 0xFF000000, + 0x00FF0000, + 0x0000FF00, + 0x000000FF +#endif + ); + } + if ( ! SDL_VideoSurface ) { + return(NULL); + } + SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT; + + /* Free the original video mode surface (is this safe?) */ + SDL_FreeSurface(mode); + + /* Set the surface completely opaque & white by default */ + SDL_memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch ); + video->glGenTextures( 1, &video->texture ); + video->glBindTexture( GL_TEXTURE_2D, video->texture ); + video->glTexImage2D( + GL_TEXTURE_2D, + 0, + video->is_32bit ? GL_RGBA : GL_RGB, + 256, + 256, + 0, + video->is_32bit ? GL_RGBA : GL_RGB, +#ifdef GL_VERSION_1_2 + video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, +#else + GL_UNSIGNED_BYTE, +#endif + NULL); + + video->UpdateRects = SDL_GL_UpdateRectsLock; +#else + SDL_SetError("Somebody forgot to #define SDL_VIDEO_OPENGL"); + return(NULL); +#endif + } + + /* Create a shadow surface if necessary */ + /* There are three conditions under which we create a shadow surface: + 1. We need a particular bits-per-pixel that we didn't get. + 2. We need a hardware palette and didn't get one. + 3. We need a software surface and got a hardware surface. + */ + if ( !(SDL_VideoSurface->flags & SDL_OPENGL) && + ( + ( !(flags&SDL_ANYFORMAT) && + (SDL_VideoSurface->format->BitsPerPixel != bpp)) || + ( (flags&SDL_HWPALETTE) && + !(SDL_VideoSurface->flags&SDL_HWPALETTE)) || + /* If the surface is in hardware, video writes are visible + as soon as they are performed, so we need to buffer them + */ + ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) && + (SDL_VideoSurface->flags&SDL_HWSURFACE)) || + ( (flags&SDL_DOUBLEBUF) && + (SDL_VideoSurface->flags&SDL_HWSURFACE) && + !(SDL_VideoSurface->flags&SDL_DOUBLEBUF)) + ) ) { + SDL_CreateShadowSurface(bpp); + if ( SDL_ShadowSurface == NULL ) { + SDL_SetError("Couldn't create shadow surface"); + return(NULL); + } + SDL_PublicSurface = SDL_ShadowSurface; + } else { + SDL_PublicSurface = SDL_VideoSurface; + } + video->info.vfmt = SDL_VideoSurface->format; + video->info.current_w = SDL_VideoSurface->w; + video->info.current_h = SDL_VideoSurface->h; + + /* We're done! */ + return(SDL_PublicSurface); +} + +/* + * Convert a surface into the video pixel format. + */ +SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface) +{ + Uint32 flags; + + if ( ! SDL_PublicSurface ) { + SDL_SetError("No video mode has been set"); + return(NULL); + } + /* Set the flags appropriate for copying to display surface */ + if (((SDL_PublicSurface->flags&SDL_HWSURFACE) == SDL_HWSURFACE) && current_video->info.blit_hw) + flags = SDL_HWSURFACE; + else + flags = SDL_SWSURFACE; +#ifdef AUTORLE_DISPLAYFORMAT + flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA)); + flags |= SDL_RLEACCELOK; +#else + flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK); +#endif + return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); +} + +/* + * Convert a surface into a format that's suitable for blitting to + * the screen, but including an alpha channel. + */ +SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface) +{ + SDL_PixelFormat *vf; + SDL_PixelFormat *format; + SDL_Surface *converted; + Uint32 flags; + /* default to ARGB8888 */ + Uint32 amask = 0xff000000; + Uint32 rmask = 0x00ff0000; + Uint32 gmask = 0x0000ff00; + Uint32 bmask = 0x000000ff; + + if ( ! SDL_PublicSurface ) { + SDL_SetError("No video mode has been set"); + return(NULL); + } + vf = SDL_PublicSurface->format; + + switch(vf->BytesPerPixel) { + case 2: + /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. + For anything else (like ARGB4444) it doesn't matter + since we have no special code for it anyway */ + if ( (vf->Rmask == 0x1f) && + (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { + rmask = 0xff; + bmask = 0xff0000; + } + break; + + case 3: + case 4: + /* Keep the video format, as long as the high 8 bits are + unused or alpha */ + if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { + rmask = 0xff; + bmask = 0xff0000; + } else if ( vf->Rmask == 0xFF00 && (vf->Bmask == 0xFF000000) ) { + amask = 0x000000FF; + rmask = 0x0000FF00; + gmask = 0x00FF0000; + bmask = 0xFF000000; + } + break; + + default: + /* We have no other optimised formats right now. When/if a new + optimised alpha format is written, add the converter here */ + break; + } + format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); + flags = SDL_PublicSurface->flags & SDL_HWSURFACE; + flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); + converted = SDL_ConvertSurface(surface, format, flags); + SDL_FreeFormat(format); + return(converted); +} + +/* + * Update a specific portion of the physical screen + */ +void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) +{ + if ( screen ) { + SDL_Rect rect; + + /* Perform some checking */ + if ( w == 0 ) + w = screen->w; + if ( h == 0 ) + h = screen->h; + if ( (int)(x+w) > screen->w ) + return; + if ( (int)(y+h) > screen->h ) + return; + + /* Fill the rectangle */ + rect.x = (Sint16)x; + rect.y = (Sint16)y; + rect.w = (Uint16)w; + rect.h = (Uint16)h; + SDL_UpdateRects(screen, 1, &rect); + } +} +void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects) +{ + int i; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( (screen->flags & (SDL_OPENGL | SDL_OPENGLBLIT)) == SDL_OPENGL ) { + SDL_SetError("OpenGL active, use SDL_GL_SwapBuffers()"); + return; + } + if ( screen == SDL_ShadowSurface ) { + /* Blit the shadow surface using saved mapping */ + SDL_Palette *pal = screen->format->palette; + SDL_Color *saved_colors = NULL; + if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { + /* simulated 8bpp, use correct physical palette */ + saved_colors = pal->colors; + if ( video->gammacols ) { + /* gamma-corrected palette */ + pal->colors = video->gammacols; + } else if ( video->physpal ) { + /* physical palette different from logical */ + pal->colors = video->physpal->colors; + } + } + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + SDL_LockCursor(); + SDL_DrawCursor(SDL_ShadowSurface); + for ( i=0; icolors = saved_colors; + } + + /* Fall through to video surface update */ + screen = SDL_VideoSurface; + } + if ( screen == SDL_VideoSurface ) { + /* Update the video surface */ + if ( screen->offset ) { + for ( i=0; ioffset_x; + rects[i].y += video->offset_y; + } + video->UpdateRects(this, numrects, rects); + for ( i=0; ioffset_x; + rects[i].y -= video->offset_y; + } + } else { + video->UpdateRects(this, numrects, rects); + } + } +} + +/* + * Performs hardware double buffering, if possible, or a full update if not. + */ +int SDL_Flip(SDL_Surface *screen) +{ + SDL_VideoDevice *video = current_video; + /* Copy the shadow surface to the video surface */ + if ( screen == SDL_ShadowSurface ) { + SDL_Rect rect; + SDL_Palette *pal = screen->format->palette; + SDL_Color *saved_colors = NULL; + if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { + /* simulated 8bpp, use correct physical palette */ + saved_colors = pal->colors; + if ( video->gammacols ) { + /* gamma-corrected palette */ + pal->colors = video->gammacols; + } else if ( video->physpal ) { + /* physical palette different from logical */ + pal->colors = video->physpal->colors; + } + } + + rect.x = 0; + rect.y = 0; + rect.w = screen->w; + rect.h = screen->h; + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + SDL_LockCursor(); + SDL_DrawCursor(SDL_ShadowSurface); + SDL_LowerBlit(SDL_ShadowSurface, &rect, + SDL_VideoSurface, &rect); + SDL_EraseCursor(SDL_ShadowSurface); + SDL_UnlockCursor(); + } else { + SDL_LowerBlit(SDL_ShadowSurface, &rect, + SDL_VideoSurface, &rect); + } + if ( saved_colors ) { + pal->colors = saved_colors; + } + + /* Fall through to video surface update */ + screen = SDL_VideoSurface; + } + if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + SDL_VideoDevice *this = current_video; + return(video->FlipHWSurface(this, SDL_VideoSurface)); + } else { + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + return(0); +} + +static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, + int firstcolor, int ncolors) +{ + SDL_Palette *pal = screen->format->palette; + SDL_Palette *vidpal; + + if ( colors != (pal->colors + firstcolor) ) { + SDL_memcpy(pal->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } + + if ( current_video && SDL_VideoSurface ) { + vidpal = SDL_VideoSurface->format->palette; + if ( (screen == SDL_ShadowSurface) && vidpal ) { + /* + * This is a shadow surface, and the physical + * framebuffer is also indexed. Propagate the + * changes to its logical palette so that + * updates are always identity blits + */ + SDL_memcpy(vidpal->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } + } + SDL_FormatChanged(screen); +} + +static int SetPalette_physical(SDL_Surface *screen, + SDL_Color *colors, int firstcolor, int ncolors) +{ + SDL_VideoDevice *video = current_video; + int gotall = 1; + + if ( video->physpal ) { + /* We need to copy the new colors, since we haven't + * already done the copy in the logical set above. + */ + SDL_memcpy(video->physpal->colors + firstcolor, + colors, ncolors * sizeof(*colors)); + } + if ( screen == SDL_ShadowSurface ) { + if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) { + /* + * The real screen is also indexed - set its physical + * palette. The physical palette does not include the + * gamma modification, we apply it directly instead, + * but this only happens if we have hardware palette. + */ + screen = SDL_VideoSurface; + } else { + /* + * The video surface is not indexed - invalidate any + * active shadow-to-video blit mappings. + */ + if ( screen->map->dst == SDL_VideoSurface ) { + SDL_InvalidateMap(screen->map); + } + if ( video->gamma ) { + if( ! video->gammacols ) { + SDL_Palette *pp = video->physpal; + if(!pp) + pp = screen->format->palette; + video->gammacols = SDL_malloc(pp->ncolors + * sizeof(SDL_Color)); + SDL_ApplyGamma(video->gamma, + pp->colors, + video->gammacols, + pp->ncolors); + } else { + SDL_ApplyGamma(video->gamma, colors, + video->gammacols + + firstcolor, + ncolors); + } + } + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + } + + if ( screen == SDL_VideoSurface ) { + SDL_Color gcolors[256]; + + if ( video->gamma ) { + SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors); + colors = gcolors; + } + gotall = video->SetColors(video, firstcolor, ncolors, colors); + if ( ! gotall ) { + /* The video flags shouldn't have SDL_HWPALETTE, and + the video driver is responsible for copying back the + correct colors into the video surface palette. + */ + ; + } + SDL_CursorPaletteChanged(); + } + return gotall; +} + +/* + * Set the physical and/or logical colormap of a surface: + * Only the screen has a physical colormap. It determines what is actually + * sent to the display. + * The logical colormap is used to map blits to/from the surface. + * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL + * + * Return nonzero if all colours were set as requested, or 0 otherwise. + */ +int SDL_SetPalette(SDL_Surface *screen, int which, + SDL_Color *colors, int firstcolor, int ncolors) +{ + SDL_Palette *pal; + int gotall; + int palsize; + + if ( !screen ) { + return 0; + } + if ( !current_video || screen != SDL_PublicSurface ) { + /* only screens have physical palettes */ + which &= ~SDL_PHYSPAL; + } else if ( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { + /* hardware palettes required for split colormaps */ + which |= SDL_PHYSPAL | SDL_LOGPAL; + } + + /* Verify the parameters */ + pal = screen->format->palette; + if( !pal ) { + return 0; /* not a palettized surface */ + } + gotall = 1; + palsize = 1 << screen->format->BitsPerPixel; + if ( ncolors > (palsize - firstcolor) ) { + ncolors = (palsize - firstcolor); + gotall = 0; + } + + if ( which & SDL_LOGPAL ) { + /* + * Logical palette change: The actual screen isn't affected, + * but the internal colormap is altered so that the + * interpretation of the pixel values (for blits etc) is + * changed. + */ + SetPalette_logical(screen, colors, firstcolor, ncolors); + } + if ( which & SDL_PHYSPAL ) { + SDL_VideoDevice *video = current_video; + /* + * Physical palette change: This doesn't affect the + * program's idea of what the screen looks like, but changes + * its actual appearance. + */ + if ( !video->physpal && !(which & SDL_LOGPAL) ) { + /* Lazy physical palette allocation */ + int size; + SDL_Palette *pp = SDL_malloc(sizeof(*pp)); + if ( !pp ) { + return 0; + } + video->physpal = pp; + pp->ncolors = pal->ncolors; + size = pp->ncolors * sizeof(SDL_Color); + pp->colors = SDL_malloc(size); + if ( !pp->colors ) { + return 0; + } + SDL_memcpy(pp->colors, pal->colors, size); + } + if ( ! SetPalette_physical(screen, + colors, firstcolor, ncolors) ) { + gotall = 0; + } + } + return gotall; +} + +int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor, + int ncolors) +{ + return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, + colors, firstcolor, ncolors); +} + +/* + * Clean up the video subsystem + */ +void SDL_VideoQuit (void) +{ + SDL_Surface *ready_to_go; + + if ( current_video ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Halt event processing before doing anything else */ + SDL_StopEventLoop(); + + /* Clean up allocated window manager items */ + if ( SDL_PublicSurface ) { + SDL_PublicSurface = NULL; + } + SDL_CursorQuit(); + + /* Just in case... */ + SDL_WM_GrabInputOff(); + + /* Clean up the system video */ + video->VideoQuit(this); + + /* Free any lingering surfaces */ + ready_to_go = SDL_ShadowSurface; + SDL_ShadowSurface = NULL; + SDL_FreeSurface(ready_to_go); + if ( SDL_VideoSurface != NULL ) { + ready_to_go = SDL_VideoSurface; + SDL_VideoSurface = NULL; + SDL_FreeSurface(ready_to_go); + } + SDL_PublicSurface = NULL; + + /* Clean up miscellaneous memory */ + if ( video->physpal ) { + SDL_free(video->physpal->colors); + SDL_free(video->physpal); + video->physpal = NULL; + } + if ( video->gammacols ) { + SDL_free(video->gammacols); + video->gammacols = NULL; + } + if ( video->gamma ) { + SDL_free(video->gamma); + video->gamma = NULL; + } + if ( video->wm_title != NULL ) { + SDL_free(video->wm_title); + video->wm_title = NULL; + } + if ( video->wm_icon != NULL ) { + SDL_free(video->wm_icon); + video->wm_icon = NULL; + } + + /* Finish cleaning up video subsystem */ + video->free(this); + current_video = NULL; + } + return; +} + +/* Load the GL driver library */ +int SDL_GL_LoadLibrary(const char *path) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int retval; + + retval = -1; + if ( video == NULL ) { + SDL_SetError("Video subsystem has not been initialized"); + } else { + if ( video->GL_LoadLibrary ) { + retval = video->GL_LoadLibrary(this, path); + } else { + SDL_SetError("No dynamic GL support in video driver"); + } + } + return(retval); +} + +void *SDL_GL_GetProcAddress(const char* proc) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + void *func; + + func = NULL; + if ( video->GL_GetProcAddress ) { + if ( video->gl_config.driver_loaded ) { + func = video->GL_GetProcAddress(this, proc); + } else { + SDL_SetError("No GL driver has been loaded"); + } + } else { + SDL_SetError("No dynamic GL support in video driver"); + } + return func; +} + +/* Set the specified GL attribute for setting up a GL video mode */ +int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) +{ + int retval; + SDL_VideoDevice *video = current_video; + + retval = 0; + switch (attr) { + case SDL_GL_RED_SIZE: + video->gl_config.red_size = value; + break; + case SDL_GL_GREEN_SIZE: + video->gl_config.green_size = value; + break; + case SDL_GL_BLUE_SIZE: + video->gl_config.blue_size = value; + break; + case SDL_GL_ALPHA_SIZE: + video->gl_config.alpha_size = value; + break; + case SDL_GL_DOUBLEBUFFER: + video->gl_config.double_buffer = value; + break; + case SDL_GL_BUFFER_SIZE: + video->gl_config.buffer_size = value; + break; + case SDL_GL_DEPTH_SIZE: + video->gl_config.depth_size = value; + break; + case SDL_GL_STENCIL_SIZE: + video->gl_config.stencil_size = value; + break; + case SDL_GL_ACCUM_RED_SIZE: + video->gl_config.accum_red_size = value; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + video->gl_config.accum_green_size = value; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + video->gl_config.accum_blue_size = value; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + video->gl_config.accum_alpha_size = value; + break; + case SDL_GL_STEREO: + video->gl_config.stereo = value; + break; + case SDL_GL_MULTISAMPLEBUFFERS: + video->gl_config.multisamplebuffers = value; + break; + case SDL_GL_MULTISAMPLESAMPLES: + video->gl_config.multisamplesamples = value; + break; + case SDL_GL_ACCELERATED_VISUAL: + video->gl_config.accelerated = value; + break; + case SDL_GL_SWAP_CONTROL: + video->gl_config.swap_control = value; + break; + default: + SDL_SetError("Unknown OpenGL attribute"); + retval = -1; + break; + } + return(retval); +} + +/* Retrieve an attribute value from the windowing system. */ +int SDL_GL_GetAttribute(SDL_GLattr attr, int* value) +{ + int retval = -1; + SDL_VideoDevice* video = current_video; + SDL_VideoDevice* this = current_video; + + if ( video->GL_GetAttribute ) { + retval = this->GL_GetAttribute(this, attr, value); + } else { + *value = 0; + SDL_SetError("GL_GetAttribute not supported"); + } + return retval; +} + +/* Perform a GL buffer swap on the current GL context */ +void SDL_GL_SwapBuffers(void) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video->screen->flags & SDL_OPENGL ) { + video->GL_SwapBuffers(this); + } else { + SDL_SetError("OpenGL video mode has not been set"); + } +} + +/* Update rects with locking */ +void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects) +{ + SDL_GL_Lock(); + SDL_GL_UpdateRects(numrects, rects); + SDL_GL_Unlock(); +} + +/* Update rects without state setting and changing (the caller is responsible for it) */ +void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects) +{ +#if SDL_VIDEO_OPENGL + SDL_VideoDevice *this = current_video; + SDL_Rect update, tmp; + int x, y, i; + + for ( i = 0; i < numrects; i++ ) + { + tmp.y = rects[i].y; + tmp.h = rects[i].h; + for ( y = 0; y <= rects[i].h / 256; y++ ) + { + tmp.x = rects[i].x; + tmp.w = rects[i].w; + for ( x = 0; x <= rects[i].w / 256; x++ ) + { + update.x = tmp.x; + update.y = tmp.y; + update.w = tmp.w; + update.h = tmp.h; + + if ( update.w > 256 ) + update.w = 256; + + if ( update.h > 256 ) + update.h = 256; + + this->glFlush(); + this->glTexSubImage2D( + GL_TEXTURE_2D, + 0, + 0, + 0, + update.w, + update.h, + this->is_32bit? GL_RGBA : GL_RGB, +#ifdef GL_VERSION_1_2 + this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, +#else + GL_UNSIGNED_BYTE, +#endif + (Uint8 *)this->screen->pixels + + this->screen->format->BytesPerPixel * update.x + + update.y * this->screen->pitch ); + + this->glFlush(); + /* + * Note the parens around the function name: + * This is because some OpenGL implementations define glTexCoord etc + * as macros, and we don't want them expanded here. + */ + this->glBegin(GL_TRIANGLE_STRIP); + (this->glTexCoord2f)( 0.0, 0.0 ); + (this->glVertex2i)( update.x, update.y ); + (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 ); + (this->glVertex2i)( update.x + update.w, update.y ); + (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) ); + (this->glVertex2i)( update.x, update.y + update.h ); + (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) ); + (this->glVertex2i)( update.x + update.w , update.y + update.h ); + this->glEnd(); + + tmp.x += 256; + tmp.w -= 256; + } + tmp.y += 256; + tmp.h -= 256; + } + } +#endif +} + +/* Lock == save current state */ +void SDL_GL_Lock() +{ +#if SDL_VIDEO_OPENGL + lock_count--; + if (lock_count==-1) + { + SDL_VideoDevice *this = current_video; + + this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */ +#ifdef GL_CLIENT_PIXEL_STORE_BIT + this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); +#endif + + this->glEnable(GL_TEXTURE_2D); + this->glEnable(GL_BLEND); + this->glDisable(GL_FOG); + this->glDisable(GL_ALPHA_TEST); + this->glDisable(GL_DEPTH_TEST); + this->glDisable(GL_SCISSOR_TEST); + this->glDisable(GL_STENCIL_TEST); + this->glDisable(GL_CULL_FACE); + + this->glBindTexture( GL_TEXTURE_2D, this->texture ); + this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + + this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel ); + this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */ + + this->glViewport(0, 0, this->screen->w, this->screen->h); + this->glMatrixMode(GL_PROJECTION); + this->glPushMatrix(); + this->glLoadIdentity(); + + this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0); + + this->glMatrixMode(GL_MODELVIEW); + this->glPushMatrix(); + this->glLoadIdentity(); + } +#endif +} + +/* Unlock == restore saved state */ +void SDL_GL_Unlock() +{ +#if SDL_VIDEO_OPENGL + lock_count++; + if (lock_count==0) + { + SDL_VideoDevice *this = current_video; + + this->glPopMatrix(); + this->glMatrixMode(GL_PROJECTION); + this->glPopMatrix(); + + this->glPopClientAttrib(); + this->glPopAttrib(); + } +#endif +} + + +void SDL_Audio_SetCaption(const char *caption); + +/* + * Sets/Gets the title and icon text of the display window, if any. + */ +void SDL_WM_SetCaption (const char *title, const char *icon) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video ) { + if ( title ) { + if ( video->wm_title ) { + SDL_free(video->wm_title); + } + video->wm_title = SDL_strdup(title); + } + if ( icon ) { + if ( video->wm_icon ) { + SDL_free(video->wm_icon); + } + video->wm_icon = SDL_strdup(icon); + } + if ( (title || icon) && (video->SetCaption != NULL) ) { + video->SetCaption(this, video->wm_title,video->wm_icon); + } + } + + /* PulseAudio can make use of this information. */ + SDL_Audio_SetCaption(title); +} + +void SDL_WM_GetCaption (char **title, char **icon) +{ + SDL_VideoDevice *video = current_video; + + if ( video ) { + if ( title ) { + *title = video->wm_title; + } + if ( icon ) { + *icon = video->wm_icon; + } + } +} + +/* Utility function used by SDL_WM_SetIcon(); + * flags & 1 for color key, flags & 2 for alpha channel. */ +static void CreateMaskFromColorKeyOrAlpha(SDL_Surface *icon, Uint8 *mask, int flags) +{ + int x, y; + Uint32 colorkey; +#define SET_MASKBIT(icon, x, y, mask) \ + mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) + + colorkey = icon->format->colorkey; + switch (icon->format->BytesPerPixel) { + case 1: { Uint8 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint8 *)icon->pixels + y*icon->pitch; + for ( x=0; xw; ++x ) { + if ( *pixels++ == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } + } + } + } + break; + + case 2: { Uint16 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint16 *)icon->pixels + + y*icon->pitch/2; + for ( x=0; xw; ++x ) { + if ( (flags & 1) && *pixels == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { + SET_MASKBIT(icon, x, y, mask); + } + pixels++; + } + } + } + break; + + case 4: { Uint32 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint32 *)icon->pixels + + y*icon->pitch/4; + for ( x=0; xw; ++x ) { + if ( (flags & 1) && *pixels == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { + SET_MASKBIT(icon, x, y, mask); + } + pixels++; + } + } + } + break; + } +} + +/* + * Sets the window manager icon for the display window. + */ +void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( icon && video->SetIcon ) { + /* Generate a mask if necessary, and create the icon! */ + if ( mask == NULL ) { + int mask_len = icon->h*(icon->w+7)/8; + int flags = 0; + mask = (Uint8 *)SDL_malloc(mask_len); + if ( mask == NULL ) { + return; + } + SDL_memset(mask, ~0, mask_len); + if ( icon->flags & SDL_SRCCOLORKEY ) flags |= 1; + if ( icon->flags & SDL_SRCALPHA ) flags |= 2; + if( flags ) { + CreateMaskFromColorKeyOrAlpha(icon, mask, flags); + } + video->SetIcon(video, icon, mask); + SDL_free(mask); + } else { + video->SetIcon(this, icon, mask); + } + } +} + +/* + * Grab or ungrab the keyboard and mouse input. + * This function returns the final grab mode after calling the + * driver dependent function. + */ +static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Only do something if we have support for grabs */ + if ( video->GrabInput == NULL ) { + return(video->input_grab); + } + + /* If the final grab mode if off, only then do we actually grab */ +#ifdef DEBUG_GRAB + printf("SDL_WM_GrabInputRaw(%d) ... ", mode); +#endif + if ( mode == SDL_GRAB_OFF ) { + if ( video->input_grab != SDL_GRAB_OFF ) { + mode = video->GrabInput(this, mode); + } + } else { + if ( video->input_grab == SDL_GRAB_OFF ) { + mode = video->GrabInput(this, mode); + } + } + if ( mode != video->input_grab ) { + video->input_grab = mode; + if ( video->CheckMouseMode ) { + video->CheckMouseMode(this); + } + } +#ifdef DEBUG_GRAB + printf("Final mode %d\n", video->input_grab); +#endif + + /* Return the final grab state */ + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + return(mode); +} +SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) +{ + SDL_VideoDevice *video = current_video; + + /* If the video isn't initialized yet, we can't do anything */ + if ( ! video ) { + return SDL_GRAB_OFF; + } + + /* Return the current mode on query */ + if ( mode == SDL_GRAB_QUERY ) { + mode = video->input_grab; + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + return(mode); + } + +#ifdef DEBUG_GRAB + printf("SDL_WM_GrabInput(%d) ... ", mode); +#endif + /* If the video surface is fullscreen, we always grab */ + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { + mode += SDL_GRAB_FULLSCREEN; + } + return(SDL_WM_GrabInputRaw(mode)); +} +static SDL_GrabMode SDL_WM_GrabInputOff(void) +{ + SDL_GrabMode mode; + + /* First query the current grab state */ + mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); + + /* Now explicitly turn off input grab */ + SDL_WM_GrabInputRaw(SDL_GRAB_OFF); + + /* Return the old state */ + return(mode); +} + +/* + * Iconify the window in window managed environments. + * A successful iconification will result in an SDL_APPACTIVE loss event. + */ +int SDL_WM_IconifyWindow(void) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int retval; + + retval = 0; + if ( video->IconifyWindow ) { + retval = video->IconifyWindow(this); + } + return(retval); +} + +/* + * Toggle fullscreen mode + */ +int SDL_WM_ToggleFullScreen(SDL_Surface *surface) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int toggled; + + toggled = 0; + if ( SDL_PublicSurface && (surface == SDL_PublicSurface) && + video->ToggleFullScreen ) { + if ( surface->flags & SDL_FULLSCREEN ) { + toggled = video->ToggleFullScreen(this, 0); + if ( toggled ) { + SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; + SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; + } + } else { + toggled = video->ToggleFullScreen(this, 1); + if ( toggled ) { + SDL_VideoSurface->flags |= SDL_FULLSCREEN; + SDL_PublicSurface->flags |= SDL_FULLSCREEN; + } + } + /* Double-check the grab state inside SDL_WM_GrabInput() */ + if ( toggled ) { + SDL_WM_GrabInput(video->input_grab); + } + } + return(toggled); +} + +/* + * Get some platform dependent window manager information + */ +int SDL_GetWMInfo (SDL_SysWMinfo *info) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video && video->GetWMInfo ) { + return(video->GetWMInfo(this, info)); + } else { + return(0); + } +} diff --git a/apps/plugins/sdl/src/video/SDL_yuv.c b/apps/plugins/sdl/src/video/SDL_yuv.c new file mode 100644 index 0000000000..eea3347b20 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_yuv.c @@ -0,0 +1,150 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the implementation of the YUV video surface support */ + +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_yuvfuncs.h" +#include "SDL_yuv_sw_c.h" + + +SDL_Overlay *SDL_CreateYUVOverlay(int w, int h, Uint32 format, + SDL_Surface *display) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + const char *yuv_hwaccel; + SDL_Overlay *overlay; + + if ( (display->flags & SDL_OPENGL) == SDL_OPENGL ) { + SDL_SetError("YUV overlays are not supported in OpenGL mode"); + return NULL; + } + + /* Display directly on video surface, if possible */ + if ( SDL_getenv("SDL_VIDEO_YUV_DIRECT") ) { + if ( (display == SDL_PublicSurface) && + ((SDL_VideoSurface->format->BytesPerPixel == 2) || + (SDL_VideoSurface->format->BytesPerPixel == 4)) ) { + display = SDL_VideoSurface; + } + } + overlay = NULL; + yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL"); + if ( ((display == SDL_VideoSurface) && video->CreateYUVOverlay) && + (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0)) ) { + overlay = video->CreateYUVOverlay(this, w, h, format, display); + } + /* If hardware YUV overlay failed ... */ + if ( overlay == NULL ) { + overlay = SDL_CreateYUV_SW(this, w, h, format, display); + } + return overlay; +} + +int SDL_LockYUVOverlay(SDL_Overlay *overlay) +{ + if ( overlay == NULL ) { + SDL_SetError("Passed NULL overlay"); + return -1; + } + return overlay->hwfuncs->Lock(current_video, overlay); +} + +void SDL_UnlockYUVOverlay(SDL_Overlay *overlay) +{ + if ( overlay == NULL ) { + return; + } + overlay->hwfuncs->Unlock(current_video, overlay); +} + +int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect) +{ + SDL_Rect src, dst; + int srcx, srcy, srcw, srch; + int dstx, dsty, dstw, dsth; + + if ( overlay == NULL || dstrect == NULL ) { + SDL_SetError("Passed NULL overlay or dstrect"); + return -1; + } + + /* Clip the rectangle to the screen area */ + srcx = 0; + srcy = 0; + srcw = overlay->w; + srch = overlay->h; + dstx = dstrect->x; + dsty = dstrect->y; + dstw = dstrect->w; + dsth = dstrect->h; + if ( dstx < 0 ) { + srcw += (dstx * overlay->w) / dstrect->w; + dstw += dstx; + srcx -= (dstx * overlay->w) / dstrect->w; + dstx = 0; + } + if ( (dstx+dstw) > current_video->screen->w ) { + int extra = (dstx+dstw - current_video->screen->w); + srcw -= (extra * overlay->w) / dstrect->w; + dstw -= extra; + } + if ( dsty < 0 ) { + srch += (dsty * overlay->h) / dstrect->h; + dsth += dsty; + srcy -= (dsty * overlay->h) / dstrect->h; + dsty = 0; + } + if ( (dsty+dsth) > current_video->screen->h ) { + int extra = (dsty+dsth - current_video->screen->h); + srch -= (extra * overlay->h) / dstrect->h; + dsth -= extra; + } + if ( srcw <= 0 || srch <= 0 || + srch <= 0 || dsth <= 0 ) { + return 0; + } + /* Ugh, I can't wait for SDL_Rect to be int values */ + src.x = srcx; + src.y = srcy; + src.w = srcw; + src.h = srch; + dst.x = dstx; + dst.y = dsty; + dst.w = dstw; + dst.h = dsth; + return overlay->hwfuncs->Display(current_video, overlay, &src, &dst); +} + +void SDL_FreeYUVOverlay(SDL_Overlay *overlay) +{ + if ( overlay == NULL ) { + return; + } + if ( overlay->hwfuncs ) { + overlay->hwfuncs->FreeHW(current_video, overlay); + } + SDL_free(overlay); +} diff --git a/apps/plugins/sdl/src/video/SDL_yuv_mmx.c b/apps/plugins/sdl/src/video/SDL_yuv_mmx.c new file mode 100644 index 0000000000..f11c432a4f --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_yuv_mmx.c @@ -0,0 +1,428 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES + +#include "SDL_stdinc.h" + +#include "mmx.h" + +/* *INDENT-OFF* */ + +static mmx_t MMX_0080w = { .ud = {0x00800080, 0x00800080} }; +static mmx_t MMX_00FFw = { .ud = {0x00ff00ff, 0x00ff00ff} }; +static mmx_t MMX_FF00w = { .ud = {0xff00ff00, 0xff00ff00} }; + +static mmx_t MMX_Ycoeff = { .uw = {0x004a, 0x004a, 0x004a, 0x004a} }; + +static mmx_t MMX_UbluRGB = { .uw = {0x0072, 0x0072, 0x0072, 0x0072} }; +static mmx_t MMX_VredRGB = { .uw = {0x0059, 0x0059, 0x0059, 0x0059} }; +static mmx_t MMX_UgrnRGB = { .uw = {0xffea, 0xffea, 0xffea, 0xffea} }; +static mmx_t MMX_VgrnRGB = { .uw = {0xffd2, 0xffd2, 0xffd2, 0xffd2} }; + +static mmx_t MMX_Ublu5x5 = { .uw = {0x0081, 0x0081, 0x0081, 0x0081} }; +static mmx_t MMX_Vred5x5 = { .uw = {0x0066, 0x0066, 0x0066, 0x0066} }; +static mmx_t MMX_Ugrn565 = { .uw = {0xffe8, 0xffe8, 0xffe8, 0xffe8} }; +static mmx_t MMX_Vgrn565 = { .uw = {0xffcd, 0xffcd, 0xffcd, 0xffcd} }; + +static mmx_t MMX_red565 = { .uw = {0xf800, 0xf800, 0xf800, 0xf800} }; +static mmx_t MMX_grn565 = { .uw = {0x07e0, 0x07e0, 0x07e0, 0x07e0} }; + +/** + This MMX assembler is my first assembler/MMX program ever. + Thus it maybe buggy. + Send patches to: + mvogt@rhrk.uni-kl.de + + After it worked fine I have "obfuscated" the code a bit to have + more parallism in the MMX units. This means I moved + initilisation around and delayed other instruction. + Performance measurement did not show that this brought any advantage + but in theory it _should_ be faster this way. + + The overall performanve gain to the C based dither was 30%-40%. + The MMX routine calculates 256bit=8RGB values in each cycle + (4 for row1 & 4 for row2) + + The red/green/blue.. coefficents are taken from the mpeg_play + player. They look nice, but I dont know if you can have + better values, to avoid integer rounding errors. + + + IMPORTANT: + ========== + + It is a requirement that the cr/cb/lum are 8 byte aligned and + the out are 16byte aligned or you will/may get segfaults + +*/ + +void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + Uint32 *row1; + Uint32 *row2; + + unsigned char* y = lum +cols*rows; // Pointer to the end + int x = 0; + row1 = (Uint32 *)out; // 32 bit target + row2 = (Uint32 *)out+cols+mod; // start of second row + mod = (mod+cols+mod)*4; // increment for row1 in byte + + __asm__ __volatile__ ( + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx,4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). + + ".align 8\n" + "1:\n" + + // create Cr (result in mm1) + "pushl %%ebx\n" + "movl 4(%%esp),%%ebx\n" + "movd (%%ebx),%%mm1\n" // 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 + "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 + "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 + "psubw %9,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 + + // create Cr_g (result in mm0) + "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 + "pmullw %10,%%mm0\n" // red*-46dec=0.7136*64 + "pmullw %11,%%mm1\n" // red*89dec=1.4013*64 + "psraw $6, %%mm0\n" // red=red/64 + "psraw $6, %%mm1\n" // red=red/64 + + // create L1 L2 (result in mm2,mm4) + // L2=lum+cols + "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 + "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "pand %12,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 + "pand %13,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 + "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 + + // create R (result in mm6) + "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 + "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 + "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 + "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 + "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 + + // create Cb (result in mm1) + "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 + "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 + "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 + "psubw %9,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 + // create Cb_g (result in mm5) + "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 + "pmullw %14,%%mm5\n" // blue*-109dec=1.7129*64 + "pmullw %15,%%mm1\n" // blue*114dec=1.78125*64 + "psraw $6, %%mm5\n" // blue=red/64 + "psraw $6, %%mm1\n" // blue=blue/64 + + // create G (result in mm7) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t + "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t + "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 + "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 + "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 + "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 + "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 + + // create B (result in mm5) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 + "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 + "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 + "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 + "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 + + // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 + "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 + "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 + // process lower lum + "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 + "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 + "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 + "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 + "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 + "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 + "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 + "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 + "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 + "movq %%mm2,(%3)\n" // wrote out ! row1 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 + "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 + "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 + "movq %%mm4,8(%3)\n" // wrote out ! row1 + + // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + // this can be done "destructive" + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 + "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 + "movq %%mm1,(%5)\n" // wrote out ! row2 + "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 + "movq %%mm5,8(%5)\n" // wrote out ! row2 + + "addl $4,%2\n" // lum+4 + "leal 16(%3),%3\n" // row1+16 + "leal 16(%5),%5\n" // row2+16 + "addl $2,(%%esp)\n" // cr+2 + "addl $2,%1\n" // cb+2 + + "addl $4,%6\n" // x+4 + "cmpl %4,%6\n" + + "jl 1b\n" + "addl %4,%2\n" // lum += cols + "addl %8,%3\n" // row1+= mod + "addl %8,%5\n" // row2+= mod + "movl $0,%6\n" // x=0 + "cmpl %7,%2\n" + "jl 1b\n" + + "addl $4,%%esp\n" // get rid of the stack slot we reserved. + "emms\n" // reset MMX registers. + : + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_VgrnRGB),"m"(MMX_VredRGB), + "m"(MMX_FF00w),"m"(MMX_00FFw),"m"(MMX_UgrnRGB), + "m"(MMX_UbluRGB) + ); +} + +void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + Uint16 *row1; + Uint16 *row2; + + unsigned char* y = lum +cols*rows; /* Pointer to the end */ + int x = 0; + row1 = (Uint16 *)out; /* 16 bit target */ + row2 = (Uint16 *)out+cols+mod; /* start of second row */ + mod = (mod+cols+mod)*2; /* increment for row1 in byte */ + + __asm__ __volatile__( + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). + + ".align 8\n" + "1:\n" + "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 + "pxor %%mm7, %%mm7\n" + "pushl %%ebx\n" + "movl 4(%%esp), %%ebx\n" + "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" + + "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 + "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 + "psubw %9, %%mm0\n" + "psubw %9, %%mm1\n" + "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 + "movq %%mm1, %%mm3\n" // Cr + "pmullw %10, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 + "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 + "pmullw %11, %%mm0\n" // Cb2blue + "pand %12, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 + "pmullw %13, %%mm3\n" // Cr2green + "movq (%2), %%mm7\n" // L2 + "pmullw %14, %%mm1\n" // Cr2red + "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 + "pmullw %15, %%mm6\n" // lum1 + "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green + "pmullw %15, %%mm7\n" // lum2 + + "movq %%mm6, %%mm4\n" // lum1 + "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 + "movq %%mm4, %%mm5\n" // lum1 + "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0 + "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0 + "psraw $6, %%mm4\n" // R1 0 .. 64 + "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1 + "psraw $6, %%mm5\n" // G1 - .. + + "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1 + "psraw $6, %%mm6\n" // B1 0 .. 64 + "packuswb %%mm4, %%mm4\n" // R1 R1 + "packuswb %%mm5, %%mm5\n" // G1 G1 + "packuswb %%mm6, %%mm6\n" // B1 B1 + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + + "pand %16, %%mm4\n" + "psllw $3, %%mm5\n" // GREEN 1 + "punpcklbw %%mm6, %%mm6\n" + "pand %17, %%mm5\n" + "pand %16, %%mm6\n" + "por %%mm5, %%mm4\n" // + "psrlw $11, %%mm6\n" // BLUE 1 + "movq %%mm3, %%mm5\n" // lum2 + "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1 + "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1 + "psraw $6, %%mm3\n" // R2 + "por %%mm6, %%mm4\n" // MM4 + "psraw $6, %%mm5\n" // G2 + "movq (%2, %4), %%mm6\n" // L3 load lum2 + "psraw $6, %%mm7\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm5, %%mm5\n" + "packuswb %%mm7, %%mm7\n" + "pand %12, %%mm6\n" // L3 + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm5, %%mm5\n" + "pmullw %15, %%mm6\n" // lum3 + "punpcklbw %%mm7, %%mm7\n" + "psllw $3, %%mm5\n" // GREEN 2 + "pand %16, %%mm7\n" + "pand %16, %%mm3\n" + "psrlw $11, %%mm7\n" // BLUE 2 + "pand %17, %%mm5\n" + "por %%mm7, %%mm3\n" + "movq (%2,%4), %%mm7\n" // L4 load lum2 + "por %%mm5, %%mm3\n" // + "psrlw $8, %%mm7\n" // L4 + "movq %%mm4, %%mm5\n" + "punpcklwd %%mm3, %%mm4\n" + "pmullw %15, %%mm7\n" // lum4 + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%3)\n" // write row1 + "movq %%mm5, 8(%3)\n" // write row1 + + "movq %%mm6, %%mm4\n" // Lum3 + "paddw %%mm0, %%mm6\n" // Lum3 +blue + + "movq %%mm4, %%mm5\n" // Lum3 + "paddw %%mm1, %%mm4\n" // Lum3 +red + "paddw %%mm2, %%mm5\n" // Lum3 +green + "psraw $6, %%mm4\n" + "movq %%mm7, %%mm3\n" // Lum4 + "psraw $6, %%mm5\n" + "paddw %%mm0, %%mm7\n" // Lum4 +blue + "psraw $6, %%mm6\n" // Lum3 +blue + "movq %%mm3, %%mm0\n" // Lum4 + "packuswb %%mm4, %%mm4\n" + "paddw %%mm1, %%mm3\n" // Lum4 +red + "packuswb %%mm5, %%mm5\n" + "paddw %%mm2, %%mm0\n" // Lum4 +green + "packuswb %%mm6, %%mm6\n" + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + "punpcklbw %%mm6, %%mm6\n" + "psllw $3, %%mm5\n" // GREEN 3 + "pand %16, %%mm4\n" + "psraw $6, %%mm3\n" // psr 6 + "psraw $6, %%mm0\n" + "pand %16, %%mm6\n" // BLUE + "pand %17, %%mm5\n" + "psrlw $11, %%mm6\n" // BLUE 3 + "por %%mm5, %%mm4\n" + "psraw $6, %%mm7\n" + "por %%mm6, %%mm4\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm0, %%mm0\n" + "packuswb %%mm7, %%mm7\n" + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm0, %%mm0\n" + "punpcklbw %%mm7, %%mm7\n" + "pand %16, %%mm3\n" + "pand %16, %%mm7\n" // BLUE + "psllw $3, %%mm0\n" // GREEN 4 + "psrlw $11, %%mm7\n" + "pand %17, %%mm0\n" + "por %%mm7, %%mm3\n" + "por %%mm0, %%mm3\n" + + "movq %%mm4, %%mm5\n" + + "punpcklwd %%mm3, %%mm4\n" + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%5)\n" + "movq %%mm5, 8(%5)\n" + + "addl $8, %6\n" + "addl $8, %2\n" + "addl $4, (%%esp)\n" + "addl $4, %1\n" + "cmpl %4, %6\n" + "leal 16(%3), %3\n" + "leal 16(%5),%5\n" // row2+16 + + "jl 1b\n" + "addl %4, %2\n" // lum += cols + "addl %8, %3\n" // row1+= mod + "addl %8, %5\n" // row2+= mod + "movl $0, %6\n" // x=0 + "cmpl %7, %2\n" + "jl 1b\n" + "addl $4, %%esp\n" // get rid of the stack slot we reserved. + "emms\n" + : + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_Ugrn565),"m"(MMX_Ublu5x5), + "m"(MMX_00FFw),"m"(MMX_Vgrn565),"m"(MMX_Vred5x5), + "m"(MMX_Ycoeff),"m"(MMX_red565),"m"(MMX_grn565) + ); +} + +/* *INDENT-ON* */ + +#endif /* GCC3 i386 inline assembly */ + diff --git a/apps/plugins/sdl/src/video/SDL_yuv_sw.c b/apps/plugins/sdl/src/video/SDL_yuv_sw.c new file mode 100644 index 0000000000..c555ce06c2 --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_yuv_sw.c @@ -0,0 +1,1299 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the software implementation of the YUV video overlay support */ + +/* This code was derived from code carrying the following copyright notices: + + * Copyright (c) 1995 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + * Copyright (c) 1995 Erik Corry + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, + * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + * Portions of this software Copyright (c) 1995 Brown University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice and the + * following two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "SDL_video.h" +#include "SDL_cpuinfo.h" +#include "SDL_stretch_c.h" +#include "SDL_yuvfuncs.h" +#include "SDL_yuv_sw_c.h" + +/* The functions used to manipulate software video overlays */ +static struct private_yuvhwfuncs sw_yuvfuncs = { + SDL_LockYUV_SW, + SDL_UnlockYUV_SW, + SDL_DisplayYUV_SW, + SDL_FreeYUV_SW +}; + +/* RGB conversion lookup tables */ +struct private_yuvhwdata { + SDL_Surface *stretch; + SDL_Surface *display; + Uint8 *pixels; + int *colortab; + Uint32 *rgb_2_pix; + void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); + void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); + + /* These are just so we don't have to allocate them separately */ + Uint16 pitches[3]; + Uint8 *planes[3]; +}; + + +/* The colorspace conversion functions */ + +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES +extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); +extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); +#endif + +static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned short* row1; + unsigned short* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = (unsigned short*) out; + row2 = row1 + cols + mod; + lum2 = lum + cols; + + mod += cols + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum++; + *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + /* Now, do second row. */ + + L = *lum2++; + *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum2++; + *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row1; + unsigned char* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = out; + row2 = row1 + cols*3 + mod*3; + lum2 = lum + cols; + + mod += cols + mod; + mod *= 3; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row1++ = (value ) & 0xFF; + *row1++ = (value >> 8) & 0xFF; + *row1++ = (value >> 16) & 0xFF; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row1++ = (value ) & 0xFF; + *row1++ = (value >> 8) & 0xFF; + *row1++ = (value >> 16) & 0xFF; + + + /* Now, do second row. */ + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row2++ = (value ) & 0xFF; + *row2++ = (value >> 8) & 0xFF; + *row2++ = (value >> 16) & 0xFF; + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row2++ = (value ) & 0xFF; + *row2++ = (value >> 8) & 0xFF; + *row2++ = (value >> 16) & 0xFF; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1; + unsigned int* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = (unsigned int*) out; + row2 = row1 + cols + mod; + lum2 = lum + cols; + + mod += cols + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + /* Now, do second row. */ + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +/* + * In this function I make use of a nasty trick. The tables have the lower + * 16 bits replicated in the upper 16. This means I can write ints and get + * the horisontal doubling for free (almost). + */ +static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1 = (unsigned int*) out; + const int next_row = cols+(mod/2); + unsigned int* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = (next_row * 3) + (mod/2); + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1++; + + L = *lum++; + row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1++; + + + /* Now, do second row. */ + + L = *lum2++; + row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2++; + + L = *lum2++; + row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2++; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row1 = out; + const int next_row = (cols*2 + mod) * 3; + unsigned char* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = next_row*3 + mod*3; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = + (value ) & 0xFF; + row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = + (value >> 8) & 0xFF; + row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = + (value >> 16) & 0xFF; + row1 += 2*3; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = + (value ) & 0xFF; + row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = + (value >> 8) & 0xFF; + row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = + (value >> 16) & 0xFF; + row1 += 2*3; + + + /* Now, do second row. */ + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = + (value ) & 0xFF; + row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = + (value >> 8) & 0xFF; + row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = + (value >> 16) & 0xFF; + row2 += 2*3; + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = + (value ) & 0xFF; + row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = + (value >> 8) & 0xFF; + row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = + (value >> 16) & 0xFF; + row2 += 2*3; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1 = (unsigned int*) out; + const int next_row = cols*2+mod; + unsigned int* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = (next_row * 3) + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1 += 2; + + L = *lum++; + row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1 += 2; + + + /* Now, do second row. */ + + L = *lum2++; + row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2 += 2; + + L = *lum2++; + row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2 += 2; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned short* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned short*) out; + + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum; lum += 2; + *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + } + + row += mod; + } +} + +static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned char*) out; + mod *= 3; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row++ = (value ) & 0xFF; + *row++ = (value >> 8) & 0xFF; + *row++ = (value >> 16) & 0xFF; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row++ = (value ) & 0xFF; + *row++ = (value >> 8) & 0xFF; + *row++ = (value >> 16) & 0xFF; + + } + row += mod; + } +} + +static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned int*) out; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + } + row += mod; + } +} + +/* + * In this function I make use of a nasty trick. The tables have the lower + * 16 bits replicated in the upper 16. This means I can write ints and get + * the horisontal doubling for free (almost). + */ +static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row = (unsigned int*) out; + const int next_row = cols+(mod/2); + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row++; + + L = *lum; lum += 2; + row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row++; + + } + row += next_row; + } +} + +static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row = out; + const int next_row = (cols*2 + mod) * 3; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = + (value ) & 0xFF; + row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = + (value >> 8) & 0xFF; + row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = + (value >> 16) & 0xFF; + row += 2*3; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = + (value ) & 0xFF; + row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = + (value >> 8) & 0xFF; + row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = + (value >> 16) & 0xFF; + row += 2*3; + + } + row += next_row; + } +} + +static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row = (unsigned int*) out; + const int next_row = cols*2+mod; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + mod+=mod; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + row[0] = row[1] = row[next_row] = row[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row += 2; + + L = *lum; lum += 2; + row[0] = row[1] = row[next_row] = row[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row += 2; + + + } + + row += next_row; + } +} + +/* + * How many 1 bits are there in the Uint32. + * Low performance, do not call often. + */ +static int number_of_bits_set( Uint32 a ) +{ + if(!a) return 0; + if(a & 1) return 1 + number_of_bits_set(a >> 1); + return(number_of_bits_set(a >> 1)); +} + +/* + * How many 0 bits are there at least significant end of Uint32. + * Low performance, do not call often. + */ +static int free_bits_at_bottom( Uint32 a ) +{ + /* assume char is 8 bits */ + if(!a) return sizeof(Uint32) * 8; + if(((Sint32)a) & 1l) return 0; + return 1 + free_bits_at_bottom ( a >> 1); +} + + +SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) +{ + SDL_Overlay *overlay; + struct private_yuvhwdata *swdata; + int *Cr_r_tab; + int *Cr_g_tab; + int *Cb_g_tab; + int *Cb_b_tab; + Uint32 *r_2_pix_alloc; + Uint32 *g_2_pix_alloc; + Uint32 *b_2_pix_alloc; + int i; + int CR, CB; + Uint32 Rmask, Gmask, Bmask; + + /* Only RGB packed pixel conversion supported */ + if ( (display->format->BytesPerPixel != 2) && + (display->format->BytesPerPixel != 3) && + (display->format->BytesPerPixel != 4) ) { + SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); + return(NULL); + } + + /* Verify that we support the format */ + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + break; + default: + SDL_SetError("Unsupported YUV format"); + return(NULL); + } + + /* Create the overlay structure */ + overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); + if ( overlay == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + SDL_memset(overlay, 0, (sizeof *overlay)); + + /* Fill in the basic members */ + overlay->format = format; + overlay->w = width; + overlay->h = height; + + /* Set up the YUV surface function structure */ + overlay->hwfuncs = &sw_yuvfuncs; + + /* Create the pixel data and lookup tables */ + swdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *swdata); + overlay->hwdata = swdata; + if ( swdata == NULL ) { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + swdata->stretch = NULL; + swdata->display = display; + swdata->pixels = (Uint8 *) SDL_malloc(width*height*2); + swdata->colortab = (int *)SDL_malloc(4*256*sizeof(int)); + Cr_r_tab = &swdata->colortab[0*256]; + Cr_g_tab = &swdata->colortab[1*256]; + Cb_g_tab = &swdata->colortab[2*256]; + Cb_b_tab = &swdata->colortab[3*256]; + swdata->rgb_2_pix = (Uint32 *)SDL_malloc(3*768*sizeof(Uint32)); + r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; + g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; + b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; + if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + + /* Generate the tables for the display surface */ + for (i=0; i<256; i++) { + /* Gamma correction (luminescence table) and chroma correction + would be done here. See the Berkeley mpeg_play sources. + */ + CB = CR = (i-128); + Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); + Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); + Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); + Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); + } + + /* + * Set up entries 0-255 in rgb-to-pixel value tables. + */ + Rmask = display->format->Rmask; + Gmask = display->format->Gmask; + Bmask = display->format->Bmask; + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); + r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); + g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); + g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); + b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); + b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); + } + + /* + * If we have 16-bit output depth, then we double the value + * in the top word. This means that we can write out both + * pixels in the pixel doubling mode with one op. It is + * harmless in the normal case as storing a 32-bit value + * through a short pointer will lose the top bits anyway. + */ + if( display->format->BytesPerPixel == 2 ) { + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; + g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; + b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; + } + } + + /* + * Spread out the values we have to the rest of the array so that + * we do not need to check for overflow. + */ + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i] = r_2_pix_alloc[256]; + r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; + g_2_pix_alloc[i] = g_2_pix_alloc[256]; + g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; + b_2_pix_alloc[i] = b_2_pix_alloc[256]; + b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; + } + + /* You have chosen wisely... */ + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + if ( display->format->BytesPerPixel == 2 ) { +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES + /* inline assembly functions */ + if ( SDL_HasMMX() && (Rmask == 0xF800) && + (Gmask == 0x07E0) && + (Bmask == 0x001F) && + (width & 15) == 0) { +/*printf("Using MMX 16-bit 565 dither\n");*/ + swdata->Display1X = Color565DitherYV12MMX1X; + } else { +/*printf("Using C 16-bit dither\n");*/ + swdata->Display1X = Color16DitherYV12Mod1X; + } +#else + swdata->Display1X = Color16DitherYV12Mod1X; +#endif + swdata->Display2X = Color16DitherYV12Mod2X; + } + if ( display->format->BytesPerPixel == 3 ) { + swdata->Display1X = Color24DitherYV12Mod1X; + swdata->Display2X = Color24DitherYV12Mod2X; + } + if ( display->format->BytesPerPixel == 4 ) { +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES + /* inline assembly functions */ + if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && + (Gmask == 0x0000FF00) && + (Bmask == 0x000000FF) && + (width & 15) == 0) { +/*printf("Using MMX 32-bit dither\n");*/ + swdata->Display1X = ColorRGBDitherYV12MMX1X; + } else { +/*printf("Using C 32-bit dither\n");*/ + swdata->Display1X = Color32DitherYV12Mod1X; + } +#else + swdata->Display1X = Color32DitherYV12Mod1X; +#endif + swdata->Display2X = Color32DitherYV12Mod2X; + } + break; + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + if ( display->format->BytesPerPixel == 2 ) { + swdata->Display1X = Color16DitherYUY2Mod1X; + swdata->Display2X = Color16DitherYUY2Mod2X; + } + if ( display->format->BytesPerPixel == 3 ) { + swdata->Display1X = Color24DitherYUY2Mod1X; + swdata->Display2X = Color24DitherYUY2Mod2X; + } + if ( display->format->BytesPerPixel == 4 ) { + swdata->Display1X = Color32DitherYUY2Mod1X; + swdata->Display2X = Color32DitherYUY2Mod2X; + } + break; + default: + /* We should never get here (caught above) */ + break; + } + + /* Find the pitch and offset values for the overlay */ + overlay->pitches = swdata->pitches; + overlay->pixels = swdata->planes; + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + overlay->pitches[0] = overlay->w; + overlay->pitches[1] = overlay->pitches[0] / 2; + overlay->pitches[2] = overlay->pitches[0] / 2; + overlay->pixels[0] = swdata->pixels; + overlay->pixels[1] = overlay->pixels[0] + + overlay->pitches[0] * overlay->h; + overlay->pixels[2] = overlay->pixels[1] + + overlay->pitches[1] * overlay->h / 2; + overlay->planes = 3; + break; + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + overlay->pitches[0] = overlay->w*2; + overlay->pixels[0] = swdata->pixels; + overlay->planes = 1; + break; + default: + /* We should never get here (caught above) */ + break; + } + + /* We're all done.. */ + return(overlay); +} + +int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) +{ + return(0); +} + +void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) +{ + return; +} + +int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) +{ + struct private_yuvhwdata *swdata; + int stretch; + int scale_2x; + SDL_Surface *display; + Uint8 *lum, *Cr, *Cb; + Uint8 *dstp; + int mod; + + swdata = overlay->hwdata; + stretch = 0; + scale_2x = 0; + if ( src->x || src->y || src->w < overlay->w || src->h < overlay->h ) { + /* The source rectangle has been clipped. + Using a scratch surface is easier than adding clipped + source support to all the blitters, plus that would + slow them down in the general unclipped case. + */ + stretch = 1; + } else if ( (src->w != dst->w) || (src->h != dst->h) ) { + if ( (dst->w == 2*src->w) && + (dst->h == 2*src->h) ) { + scale_2x = 1; + } else { + stretch = 1; + } + } + if ( stretch ) { + if ( ! swdata->stretch ) { + display = swdata->display; + swdata->stretch = SDL_CreateRGBSurface( + SDL_SWSURFACE, + overlay->w, overlay->h, + display->format->BitsPerPixel, + display->format->Rmask, + display->format->Gmask, + display->format->Bmask, 0); + if ( ! swdata->stretch ) { + return(-1); + } + } + display = swdata->stretch; + } else { + display = swdata->display; + } + switch (overlay->format) { + case SDL_YV12_OVERLAY: + lum = overlay->pixels[0]; + Cr = overlay->pixels[1]; + Cb = overlay->pixels[2]; + break; + case SDL_IYUV_OVERLAY: + lum = overlay->pixels[0]; + Cr = overlay->pixels[2]; + Cb = overlay->pixels[1]; + break; + case SDL_YUY2_OVERLAY: + lum = overlay->pixels[0]; + Cr = lum + 3; + Cb = lum + 1; + break; + case SDL_UYVY_OVERLAY: + lum = overlay->pixels[0]+1; + Cr = lum + 1; + Cb = lum - 1; + break; + case SDL_YVYU_OVERLAY: + lum = overlay->pixels[0]; + Cr = lum + 1; + Cb = lum + 3; + break; + default: + SDL_SetError("Unsupported YUV format in blit"); + return(-1); + } + if ( SDL_MUSTLOCK(display) ) { + if ( SDL_LockSurface(display) < 0 ) { + return(-1); + } + } + if ( stretch ) { + dstp = (Uint8 *)swdata->stretch->pixels; + } else { + dstp = (Uint8 *)display->pixels + + dst->x * display->format->BytesPerPixel + + dst->y * display->pitch; + } + mod = (display->pitch / display->format->BytesPerPixel); + + if ( scale_2x ) { + mod -= (overlay->w * 2); + swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, + lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); + } else { + mod -= overlay->w; + swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, + lum, Cr, Cb, dstp, overlay->h, overlay->w, mod); + } + if ( SDL_MUSTLOCK(display) ) { + SDL_UnlockSurface(display); + } + if ( stretch ) { + display = swdata->display; + SDL_SoftStretch(swdata->stretch, src, display, dst); + } + SDL_UpdateRects(display, 1, dst); + + return(0); +} + +void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) +{ + struct private_yuvhwdata *swdata; + + swdata = overlay->hwdata; + if ( swdata ) { + if ( swdata->stretch ) { + SDL_FreeSurface(swdata->stretch); + } + if ( swdata->pixels ) { + SDL_free(swdata->pixels); + } + if ( swdata->colortab ) { + SDL_free(swdata->colortab); + } + if ( swdata->rgb_2_pix ) { + SDL_free(swdata->rgb_2_pix); + } + SDL_free(swdata); + overlay->hwdata = NULL; + } +} diff --git a/apps/plugins/sdl/src/video/SDL_yuv_sw_c.h b/apps/plugins/sdl/src/video/SDL_yuv_sw_c.h new file mode 100644 index 0000000000..5aea3a5add --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_yuv_sw_c.h @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "SDL_sysvideo.h" + +/* This is the software implementation of the YUV video overlay support */ + +extern SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display); + +extern int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay); + +extern void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay); + +extern int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst); + +extern void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay); diff --git a/apps/plugins/sdl/src/video/SDL_yuvfuncs.h b/apps/plugins/sdl/src/video/SDL_yuvfuncs.h new file mode 100644 index 0000000000..cb496b6adf --- /dev/null +++ b/apps/plugins/sdl/src/video/SDL_yuvfuncs.h @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the definition of the YUV video surface function structure */ + +#include "SDL_video.h" +#include "SDL_sysvideo.h" + +#ifndef _THIS +#define _THIS SDL_VideoDevice *_this +#endif +struct private_yuvhwfuncs { + int (*Lock)(_THIS, SDL_Overlay *overlay); + void (*Unlock)(_THIS, SDL_Overlay *overlay); + int (*Display)(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst); + void (*FreeHW)(_THIS, SDL_Overlay *overlay); +}; diff --git a/apps/plugins/sdl/src/video/Xext/README b/apps/plugins/sdl/src/video/Xext/README new file mode 100644 index 0000000000..a16ea68444 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/README @@ -0,0 +1,10 @@ + +The reason these libraries are built outside of the standard XFree86 +tree is so that they can be linked as shared object code directly into +SDL without causing any symbol collisions with code in the application. + +You can't link static library code into shared libraries on non-x86 +Linux platforms. Since these libraries haven't become standard yet, +we'll just include them directly. + +These sources are synchronized with XFree86 4.2.1 diff --git a/apps/plugins/sdl/src/video/Xext/XME/xme.c b/apps/plugins/sdl/src/video/Xext/XME/xme.c new file mode 100644 index 0000000000..2cead35ada --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/XME/xme.c @@ -0,0 +1,410 @@ +/* + * Copyright 1993-2001 by Xi Graphics, Inc. + * All Rights Reserved. + * + * Please see the LICENSE file accompanying this distribution for licensing + * information. + * + * Please send any bug fixes and modifications to src@xig.com. + * + * $XiGId: xme.c,v 1.2 2001/11/30 21:56:59 jon Exp $ + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES + +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif + +#include +#include +#include +#include "../extensions/Xext.h" +#include "../extensions/extutil.h" + +/*****************************************************************************/ + + +#define XIGMISC_PROTOCOL_NAME "XiG-SUNDRY-NONSTANDARD" +#define XIGMISC_MAJOR_VERSION 2 +#define XIGMISC_MINOR_VERSION 0 + +#define XiGMiscNumberEvents 0 + +#define X_XiGMiscQueryVersion 0 +#define X_XiGMiscQueryViews 1 +#define X_XiGMiscQueryResolutions 2 +#define X_XiGMiscChangeResolution 3 +#define X_XiGMiscFullScreen 4 + +#define sz_xXiGMiscQueryVersionReq 8 +#define sz_xXiGMiscQueryViewsReq 8 +#define sz_xXiGMiscQueryResolutionsReq 8 +#define sz_xXiGMiscChangeResolutionReq 16 +#define sz_xXiGMiscFullScreenReq 16 + +#define sz_xXiGMiscQueryVersionReply 32 +#define sz_xXiGMiscQueryViewsReply 32 +#define sz_xXiGMiscQueryResolutionsReply 32 +#define sz_xXiGMiscQueryFullScreenReply 32 + +/*******************************************************************/ + +typedef struct { + CARD8 reqType; /* always codes->major_opcode */ + CARD8 xigmiscReqType; /* always X_XiGMiscQueryVersion */ + CARD16 length; + CARD16 major; + CARD16 minor; +} xXiGMiscQueryVersionReq; + +typedef struct { + CARD8 reqType; /* always codes->major_opcode */ + CARD8 xigmiscReqType; /* always X_XiGMiscQueryViews */ + CARD16 length; + CARD8 screen; + CARD8 pad0; + CARD16 pad1; +} xXiGMiscQueryViewsReq; + +typedef struct { + CARD8 reqType; /* always codes->major_opcode */ + CARD8 xigmiscReqType; /* always X_XiGMiscQueryResolutions */ + CARD16 length; + CARD8 screen; + CARD8 view; + CARD16 pad0; +} xXiGMiscQueryResolutionsReq; + +typedef struct { + CARD8 reqType; /* always codes->major_opcode */ + CARD8 xigmiscReqType; /* always X_XiGMiscChangeResolution */ + CARD16 length; + CARD8 screen; + CARD8 view; + CARD16 pad0; + CARD16 width; + CARD16 height; + INT32 refresh; +} xXiGMiscChangeResolutionReq; + +typedef struct { + CARD8 reqType; /* always codes->major_opcode */ + CARD8 xigmiscReqType; /* always X_XiGMiscFullScreen */ + CARD16 length; + CARD8 screen; + CARD8 pad0; + CARD16 pad1; + CARD32 window; + CARD32 cmap; +} xXiGMiscFullScreenReq; + +/*******************************************************************/ + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + CARD16 major; + CARD16 minor; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xXiGMiscQueryVersionReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + CARD32 nviews; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xXiGMiscQueryViewsReply; + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 pad0; + CARD16 sequenceNumber; + CARD32 length; + CARD16 active; + CARD16 nresolutions; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; +} xXiGMiscQueryResolutionsReply; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL success; + CARD16 sequenceNumber; + CARD32 length; + CARD32 pad1; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} xXiGMiscFullScreenReply; + +/*******************************************************************/ + +typedef struct { + INT16 x; + INT16 y; + CARD16 w; + CARD16 h; +} XiGMiscViewInfo; + +typedef struct { + CARD16 width; + CARD16 height; + INT32 refresh; +} XiGMiscResolutionInfo; + +/*****************************************************************************/ + +static XExtensionInfo *xigmisc_info = NULL; +static char *xigmisc_extension_name = XIGMISC_PROTOCOL_NAME; + +#define XiGMiscCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xigmisc_extension_name, val) +#define XiGMiscSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, xigmisc_extension_name) + +#if defined(__STDC__) && !defined(UNIXCPP) +#define XiGMiscGetReq(name,req,info) GetReq (name, req); \ + req->reqType = info->codes->major_opcode; \ + req->xigmiscReqType = X_##name; + +#define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \ + req->reqType = info->codes->major_opcode; \ + req->xigmicReqType = X_##name; +#else +#define XiGMiscGetReq(name,req,info) GetReq (name, req); \ + req->reqType = info->codes->major_opcode; \ + req->xigmiscReqType = X_/**/name; +#define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \ + req->reqType = info->codes->major_opcode; \ + req->xigmiscReqType = X_/**/name; +#endif + + + +/* + * find_display - locate the display info block + */ +static int XiGMiscCloseDisplay(); + +static XExtensionHooks xigmisc_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + XiGMiscCloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + + +static XEXT_GENERATE_CLOSE_DISPLAY (XiGMiscCloseDisplay, xigmisc_info) + +static XEXT_GENERATE_FIND_DISPLAY (XiGMiscFindDisplay, xigmisc_info, + xigmisc_extension_name, + &xigmisc_extension_hooks, XiGMiscNumberEvents, NULL) + + +/*****************************************************************************/ + +Bool XiGMiscQueryVersion(Display *dpy, int *major, int *minor) +{ + int opcode, event, error; + xXiGMiscQueryVersionReq *req; + xXiGMiscQueryVersionReply rep; + XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); + + if (!XQueryExtension(dpy, XIGMISC_PROTOCOL_NAME, &opcode, &event, &error)) + return xFalse; + + XiGMiscCheckExtension(dpy, info, xFalse); + + LockDisplay (dpy); + XiGMiscGetReq (XiGMiscQueryVersion, req, info); + + req->major = XIGMISC_MAJOR_VERSION; + req->minor = XIGMISC_MINOR_VERSION; + + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return xFalse; + } + + *major = rep.major; + *minor = rep.minor; + UnlockDisplay(dpy); + SyncHandle(); + + return xTrue; +} + +int XiGMiscQueryViews(Display *dpy, int screen, XiGMiscViewInfo **pviews) +{ + int n, size; + XiGMiscViewInfo *views; + xXiGMiscQueryViewsReq *req; + xXiGMiscQueryViewsReply rep; + XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); + XiGMiscCheckExtension(dpy, info, 0); + + LockDisplay (dpy); + XiGMiscGetReq (XiGMiscQueryViews, req, info); + req->screen = screen; + + if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + n = rep.nviews; + + if (n > 0) { + size = sizeof(XiGMiscViewInfo) * n; + views = (XiGMiscViewInfo*)Xmalloc(size); + if (!views) { + _XEatData(dpy, (unsigned long)size); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + _XReadPad(dpy, (void*)views, size); + + *pviews = views; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return n; +} + +int XiGMiscQueryResolutions(Display *dpy, int screen, int view, int *pactive, XiGMiscResolutionInfo **presolutions) +{ + int n, size; + XiGMiscResolutionInfo *resolutions; + xXiGMiscQueryResolutionsReq *req; + xXiGMiscQueryResolutionsReply rep; + XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); + XiGMiscCheckExtension(dpy, info, 0); + + LockDisplay (dpy); + XiGMiscGetReq (XiGMiscQueryResolutions, req, info); + req->screen = screen; + req->view = view; + + if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + n = rep.nresolutions; + + if (n > 0) { + size = sizeof(XiGMiscResolutionInfo) * n; + resolutions = (XiGMiscResolutionInfo*)Xmalloc(size); + if (!resolutions) { + _XEatData(dpy, (unsigned long)size); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + _XReadPad(dpy, (void*)resolutions, size); + + *presolutions = resolutions; + *pactive = rep.active; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return n; +} + +void XiGMiscChangeResolution(Display *dpy, int screen, int view, int width, int height, int refresh) +{ + xXiGMiscChangeResolutionReq *req; + XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); + + XiGMiscSimpleCheckExtension(dpy, info); + + LockDisplay (dpy); + XiGMiscGetReq (XiGMiscChangeResolution, req, info); + req->screen = screen; + req->view = view; + req->width = width; + req->height = height; + req->refresh = refresh; + + UnlockDisplay(dpy); + SyncHandle(); +} + + +Bool XiGMiscFullScreen(Display *dpy, int screen, XID window, XID cmap) +{ + xXiGMiscFullScreenReq *req; + xXiGMiscFullScreenReply rep; + XExtDisplayInfo *info = XiGMiscFindDisplay(dpy); + + XiGMiscCheckExtension(dpy, info, xFalse); + + LockDisplay (dpy); + XiGMiscGetReq (XiGMiscFullScreen, req, info); + req->screen = screen; + req->pad0 = 0; + req->pad1 = 0; + req->window = window; + req->cmap = cmap; + + if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return xFalse; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return (rep.success ? xTrue : xFalse); +} + + +/* SDL addition from Ryan: free memory used by xme. */ +void XiGMiscDestroy(void) +{ + if (xigmisc_info) { + XextDestroyExtension(xigmisc_info); + xigmisc_info = NULL; + } +} + diff --git a/apps/plugins/sdl/src/video/Xext/Xinerama/Xinerama.c b/apps/plugins/sdl/src/video/Xext/Xinerama/Xinerama.c new file mode 100644 index 0000000000..4ff42ebfe9 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xinerama/Xinerama.c @@ -0,0 +1,324 @@ +/* $Xorg: XPanoramiX.c,v 1.4 2000/08/17 19:45:51 cpqbld Exp $ */ +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ +/* $XFree86: xc/lib/Xinerama/Xinerama.c,v 1.2 2001/07/23 17:20:28 dawes Exp $ */ + +#define NEED_EVENTS +#define NEED_REPLIES + +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif + +#include +#include "../extensions/Xext.h" +#include "../extensions/extutil.h" /* in ../include */ +#include "../extensions/panoramiXext.h" +#include "../extensions/panoramiXproto.h" /* in ../include */ +#include "../extensions/Xinerama.h" + +static XExtensionInfo _panoramiX_ext_info_data; +static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data; +static /* const */ char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME; + +#define PanoramiXCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, panoramiX_extension_name, val) +#define PanoramiXSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, panoramiX_extension_name) + +static int close_display(); +static /* const */ XExtensionHooks panoramiX_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, panoramiX_ext_info, + panoramiX_extension_name, + &panoramiX_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, panoramiX_ext_info) + + + +/**************************************************************************** + * * + * PanoramiX public interfaces * + * * + ****************************************************************************/ + +Bool SDL_NAME(XPanoramiXQueryExtension) ( + Display *dpy, + int *event_basep, + int *error_basep +) +{ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Status SDL_NAME(XPanoramiXQueryVersion)( + Display *dpy, + int *major_versionp, + int *minor_versionp +) +{ + XExtDisplayInfo *info = find_display (dpy); + xPanoramiXQueryVersionReply rep; + register xPanoramiXQueryVersionReq *req; + + PanoramiXCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (PanoramiXQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_PanoramiXQueryVersion; + req->clientMajor = PANORAMIX_MAJOR_VERSION; + req->clientMinor = PANORAMIX_MINOR_VERSION; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + *major_versionp = rep.majorVersion; + *minor_versionp = rep.minorVersion; + UnlockDisplay (dpy); + SyncHandle (); + return 1; +} + +SDL_NAME(XPanoramiXInfo) *SDL_NAME(XPanoramiXAllocInfo)(void) +{ + return (SDL_NAME(XPanoramiXInfo) *) Xmalloc (sizeof (SDL_NAME(XPanoramiXInfo))); +} + +Status SDL_NAME(XPanoramiXGetState) ( + Display *dpy, + Drawable drawable, + SDL_NAME(XPanoramiXInfo) *panoramiX_info +) +{ + XExtDisplayInfo *info = find_display (dpy); + xPanoramiXGetStateReply rep; + register xPanoramiXGetStateReq *req; + + PanoramiXCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (PanoramiXGetState, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_PanoramiXGetState; + req->window = drawable; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + UnlockDisplay (dpy); + SyncHandle (); + panoramiX_info->window = rep.window; + panoramiX_info->State = rep.state; + return 1; +} + +Status SDL_NAME(XPanoramiXGetScreenCount) ( + Display *dpy, + Drawable drawable, + SDL_NAME(XPanoramiXInfo) *panoramiX_info +) +{ + XExtDisplayInfo *info = find_display (dpy); + xPanoramiXGetScreenCountReply rep; + register xPanoramiXGetScreenCountReq *req; + + PanoramiXCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (PanoramiXGetScreenCount, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_PanoramiXGetScreenCount; + req->window = drawable; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + UnlockDisplay (dpy); + SyncHandle (); + panoramiX_info->window = rep.window; + panoramiX_info->ScreenCount = rep.ScreenCount; + return 1; +} + +Status SDL_NAME(XPanoramiXGetScreenSize) ( + Display *dpy, + Drawable drawable, + int screen_num, + SDL_NAME(XPanoramiXInfo) *panoramiX_info +) +{ + XExtDisplayInfo *info = find_display (dpy); + xPanoramiXGetScreenSizeReply rep; + register xPanoramiXGetScreenSizeReq *req; + + PanoramiXCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (PanoramiXGetScreenSize, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_PanoramiXGetScreenSize; + req->window = drawable; + req->screen = screen_num; /* need to define */ + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + UnlockDisplay (dpy); + SyncHandle (); + panoramiX_info->window = rep.window; + panoramiX_info->screen = rep.screen; + panoramiX_info->width = rep.width; + panoramiX_info->height = rep.height; + return 1; +} + +/*******************************************************************\ + Alternate interface to make up for shortcomings in the original, + namely, the omission of the screen origin. The new interface is + in the "Xinerama" namespace instead of "PanoramiX". +\*******************************************************************/ + +Bool SDL_NAME(XineramaQueryExtension) ( + Display *dpy, + int *event_base, + int *error_base +) +{ + return SDL_NAME(XPanoramiXQueryExtension)(dpy, event_base, error_base); +} + +Status SDL_NAME(XineramaQueryVersion)( + Display *dpy, + int *major, + int *minor +) +{ + return SDL_NAME(XPanoramiXQueryVersion)(dpy, major, minor); +} + +Bool SDL_NAME(XineramaIsActive)(Display *dpy) +{ + xXineramaIsActiveReply rep; + xXineramaIsActiveReq *req; + XExtDisplayInfo *info = find_display (dpy); + + if(!XextHasExtension(info)) + return False; /* server doesn't even have the extension */ + + LockDisplay (dpy); + GetReq (XineramaIsActive, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_XineramaIsActive; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + UnlockDisplay (dpy); + SyncHandle (); + return rep.state; +} + +#include + +SDL_NAME(XineramaScreenInfo) * +SDL_NAME(XineramaQueryScreens)( + Display *dpy, + int *number +) +{ + XExtDisplayInfo *info = find_display (dpy); + xXineramaQueryScreensReply rep; + xXineramaQueryScreensReq *req; + SDL_NAME(XineramaScreenInfo) *scrnInfo = NULL; + + PanoramiXCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (XineramaQueryScreens, req); + req->reqType = info->codes->major_opcode; + req->panoramiXReqType = X_XineramaQueryScreens; + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } + + if(rep.number) { + if((scrnInfo = Xmalloc(sizeof(SDL_NAME(XineramaScreenInfo)) * rep.number))) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < rep.number; i++) { + _XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo); + scrnInfo[i].screen_number = i; + scrnInfo[i].x_org = scratch.x_org; + scrnInfo[i].y_org = scratch.y_org; + scrnInfo[i].width = scratch.width; + scrnInfo[i].height = scratch.height; + } + + *number = rep.number; + } else + _XEatData(dpy, rep.length << 2); + } + + UnlockDisplay (dpy); + SyncHandle (); + return scrnInfo; +} + + + diff --git a/apps/plugins/sdl/src/video/Xext/Xv/Xv.c b/apps/plugins/sdl/src/video/Xext/Xv/Xv.c new file mode 100644 index 0000000000..7147b9e8cb --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xv/Xv.c @@ -0,0 +1,1151 @@ +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/lib/Xv/Xv.c,v 1.15 2001/05/11 08:23:22 alanh Exp $ */ +/* +** File: +** +** Xv.c --- Xv library extension module. +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 26.06.91 Carver +** - changed XvFreeAdaptors to XvFreeAdaptorInfo +** - changed XvFreeEncodings to XvFreeEncodingInfo +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 240.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include +#include "Xvlibint.h" +#include "../extensions/Xext.h" +#include +#include "../extensions/extutil.h" + +static XExtensionInfo _xv_info_data; +static XExtensionInfo *xv_info = &_xv_info_data; +static char *xv_extension_name = XvName; + +#define XvCheckExtension(dpy, i, val) \ + XextCheckExtension(dpy, i, xv_extension_name, val) + +static char *xv_error_string(); +static int xv_close_display(); +static Bool xv_wire_to_event(); + +static XExtensionHooks xv_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + xv_close_display, /* close_display */ + xv_wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + xv_error_string /* error_string */ +}; + + +static char *xv_error_list[] = +{ + "BadPort", /* XvBadPort */ + "BadEncoding", /* XvBadEncoding */ + "BadControl" /* XvBadControl */ +}; + +static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info) + + +static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info, + xv_extension_name, + &xv_extension_hooks, + XvNumEvents, NULL) + + +static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name, + XvNumErrors, xv_error_list) + + +int +SDL_NAME(XvQueryExtension)( + Display *dpy, + unsigned int *p_version, + unsigned int *p_revision, + unsigned int *p_requestBase, + unsigned int *p_eventBase, + unsigned int *p_errorBase +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryExtensionReq *req; + xvQueryExtensionReply rep; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(QueryExtension, req); + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return XvBadExtension; + } + + *p_version = rep.version; + *p_revision = rep.revision; + *p_requestBase = info->codes->major_opcode; + *p_eventBase = info->codes->first_event; + *p_errorBase = info->codes->first_error; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvQueryAdaptors)( + Display *dpy, + Window window, + unsigned int *p_nAdaptors, + SDL_NAME(XvAdaptorInfo) **p_pAdaptors +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryAdaptorsReq *req; + xvQueryAdaptorsReply rep; + int size,ii,jj; + char *name; + SDL_NAME(XvAdaptorInfo) *pas, *pa; + SDL_NAME(XvFormat) *pfs, *pf; + char *buffer; + union + { + char *buffer; + char *string; + xvAdaptorInfo *pa; + xvFormat *pf; + } u; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(QueryAdaptors, req); + req->window = window; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + size = rep.length << 2; + if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + _XRead (dpy, buffer, size); + + u.buffer = buffer; + + /* GET INPUT ADAPTORS */ + + if (rep.num_adaptors == 0) { + pas = NULL; + } else { + size = rep.num_adaptors*sizeof(SDL_NAME(XvAdaptorInfo)); + if ((pas=(SDL_NAME(XvAdaptorInfo) *)Xmalloc(size))==NULL) { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + } + + /* INIT ADAPTOR FIELDS */ + + pa = pas; + for (ii=0; iinum_adaptors = 0; + pa->name = (char *)NULL; + pa->formats = (SDL_NAME(XvFormat) *)NULL; + pa++; + } + + pa = pas; + for (ii=0; iitype = u.pa->type; + pa->base_id = u.pa->base_id; + pa->num_ports = u.pa->num_ports; + pa->num_formats = u.pa->num_formats; + pa->num_adaptors = rep.num_adaptors - ii; + + /* GET ADAPTOR NAME */ + + size = u.pa->name_size; + u.buffer += (sz_xvAdaptorInfo + 3) & ~3; + + if ( (name = (char *)Xmalloc(size+1)) == NULL) + { + SDL_NAME(XvFreeAdaptorInfo)(pas); + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + SDL_strlcpy(name, u.string, size); + pa->name = name; + + u.buffer += (size + 3) & ~3; + + /* GET FORMATS */ + + size = pa->num_formats*sizeof(SDL_NAME(XvFormat)); + if ((pfs=(SDL_NAME(XvFormat) *)Xmalloc(size))==NULL) { + SDL_NAME(XvFreeAdaptorInfo)(pas); + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + + pf = pfs; + for (jj=0; jjnum_formats; jj++) { + pf->depth = u.pf->depth; + pf->visual_id = u.pf->visual; + pf++; + + u.buffer += (sz_xvFormat + 3) & ~3; + } + + pa->formats = pfs; + + pa++; + + } + + *p_nAdaptors = rep.num_adaptors; + *p_pAdaptors = pas; + + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + + return (Success); +} + + +void +SDL_NAME(XvFreeAdaptorInfo)(SDL_NAME(XvAdaptorInfo) *pAdaptors) +{ + + SDL_NAME(XvAdaptorInfo) *pa; + int ii; + + if (!pAdaptors) return; + + pa = pAdaptors; + + for (ii=0; iinum_adaptors; ii++, pa++) + { + if (pa->name) + { + Xfree(pa->name); + } + if (pa->formats) + { + Xfree(pa->formats); + } + } + + Xfree(pAdaptors); +} + +int +SDL_NAME(XvQueryEncodings)( + Display *dpy, + XvPortID port, + unsigned int *p_nEncodings, + SDL_NAME(XvEncodingInfo) **p_pEncodings +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryEncodingsReq *req; + xvQueryEncodingsReply rep; + int size, jj; + char *name; + SDL_NAME(XvEncodingInfo) *pes, *pe; + char *buffer; + union + { + char *buffer; + char *string; + xvEncodingInfo *pe; + } u; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(QueryEncodings, req); + req->port = port; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + size = rep.length << 2; + if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + _XRead (dpy, buffer, size); + + u.buffer = buffer; + + /* GET ENCODINGS */ + + size = rep.num_encodings*sizeof(SDL_NAME(XvEncodingInfo)); + if ( (pes = (SDL_NAME(XvEncodingInfo) *)Xmalloc(size)) == NULL) { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + + /* INITIALIZE THE ENCODING POINTER */ + + pe = pes; + for (jj=0; jjname = (char *)NULL; + pe->num_encodings = 0; + pe++; + } + + pe = pes; + for (jj=0; jjencoding_id = u.pe->encoding; + pe->width = u.pe->width; + pe->height = u.pe->height; + pe->rate.numerator = u.pe->rate.numerator; + pe->rate.denominator = u.pe->rate.denominator; + pe->num_encodings = rep.num_encodings - jj; + + size = u.pe->name_size; + u.buffer += (sz_xvEncodingInfo + 3) & ~3; + + if ( (name = (char *)Xmalloc(size+1)) == NULL) { + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadAlloc); + } + SDL_strlcpy(name, u.string, size); + pe->name = name; + pe++; + + u.buffer += (size + 3) & ~3; + } + + *p_nEncodings = rep.num_encodings; + *p_pEncodings = pes; + + Xfree(buffer); + UnlockDisplay(dpy); + SyncHandle(); + + return (Success); +} + +void +SDL_NAME(XvFreeEncodingInfo)(SDL_NAME(XvEncodingInfo) *pEncodings) +{ + + SDL_NAME(XvEncodingInfo) *pe; + int ii; + + if (!pEncodings) return; + + pe = pEncodings; + + for (ii=0; iinum_encodings; ii++, pe++) { + if (pe->name) Xfree(pe->name); + } + + Xfree(pEncodings); +} + +int +SDL_NAME(XvPutVideo)( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvPutVideoReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(PutVideo, req); + + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvPutStill)( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvPutStillReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(PutStill, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvGetVideo)( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvGetVideoReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(GetVideo, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvGetStill)( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + int vx, int vy, + unsigned int vw, unsigned int vh, + int dx, int dy, + unsigned int dw, unsigned int dh +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvGetStillReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(GetStill, req); + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->vid_x = vx; + req->vid_y = vy; + req->vid_w = vw; + req->vid_h = vh; + req->drw_x = dx; + req->drw_y = dy; + req->drw_w = dw; + req->drw_h = dh; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvStopVideo)( + Display *dpy, + XvPortID port, + Drawable draw +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvStopVideoReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(StopVideo, req); + req->port = port; + req->drawable = draw; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvGrabPort)( + Display *dpy, + XvPortID port, + Time time +){ + XExtDisplayInfo *info = xv_find_display(dpy); + int result; + xvGrabPortReply rep; + xvGrabPortReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(GrabPort, req); + req->port = port; + req->time = time; + + if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0) + rep.result = GrabSuccess; + + result = rep.result; + + UnlockDisplay(dpy); + SyncHandle(); + + return result; +} + +int +SDL_NAME(XvUngrabPort)( + Display *dpy, + XvPortID port, + Time time +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvUngrabPortReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(UngrabPort, req); + req->port = port; + req->time = time; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvSelectVideoNotify)( + Display *dpy, + Drawable drawable, + Bool onoff +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvSelectVideoNotifyReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(SelectVideoNotify, req); + req->drawable = drawable; + req->onoff = onoff; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvSelectPortNotify)( + Display *dpy, + XvPortID port, + Bool onoff +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvSelectPortNotifyReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(SelectPortNotify, req); + req->port = port; + req->onoff = onoff; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int +SDL_NAME(XvSetPortAttribute) ( + Display *dpy, + XvPortID port, + Atom attribute, + int value +) +{ + XExtDisplayInfo *info = xv_find_display(dpy); + xvSetPortAttributeReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(SetPortAttribute, req); + req->port = port; + req->attribute = attribute; + req->value = value; + + UnlockDisplay(dpy); + SyncHandle(); + + return (Success); +} + +int +SDL_NAME(XvGetPortAttribute) ( + Display *dpy, + XvPortID port, + Atom attribute, + int *p_value +) +{ + XExtDisplayInfo *info = xv_find_display(dpy); + xvGetPortAttributeReq *req; + xvGetPortAttributeReply rep; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(GetPortAttribute, req); + req->port = port; + req->attribute = attribute; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + *p_value = rep.value; + + UnlockDisplay(dpy); + SyncHandle(); + + return (Success); +} + +int +SDL_NAME(XvQueryBestSize)( + Display *dpy, + XvPortID port, + Bool motion, + unsigned int vid_w, + unsigned int vid_h, + unsigned int drw_w, + unsigned int drw_h, + unsigned int *p_actual_width, + unsigned int *p_actual_height +) +{ + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryBestSizeReq *req; + xvQueryBestSizeReply rep; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + XvGetReq(QueryBestSize, req); + req->port = port; + req->motion = motion; + req->vid_w = vid_w; + req->vid_h = vid_h; + req->drw_w = drw_w; + req->drw_h = drw_h; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return(XvBadReply); + } + + *p_actual_width = rep.actual_width; + *p_actual_height = rep.actual_height; + + UnlockDisplay(dpy); + SyncHandle(); + + return (Success); +} + + +SDL_NAME(XvAttribute)* +SDL_NAME(XvQueryPortAttributes)(Display *dpy, XvPortID port, int *num) +{ + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryPortAttributesReq *req; + xvQueryPortAttributesReply rep; + SDL_NAME(XvAttribute) *ret = NULL; + + *num = 0; + + XvCheckExtension(dpy, info, NULL); + + LockDisplay(dpy); + + XvGetReq(QueryPortAttributes, req); + req->port = port; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return ret; + } + + if(rep.num_attributes) { + int size = (rep.num_attributes * sizeof(SDL_NAME(XvAttribute))) + rep.text_size; + + if((ret = Xmalloc(size))) { + char* marker = (char*)(&ret[rep.num_attributes]); + xvAttributeInfo Info; + int i; + + for(i = 0; i < rep.num_attributes; i++) { + _XRead(dpy, (char*)(&Info), sz_xvAttributeInfo); + ret[i].flags = (int)Info.flags; + ret[i].min_value = Info.min; + ret[i].max_value = Info.max; + ret[i].name = marker; + _XRead(dpy, marker, Info.size); + marker += Info.size; + (*num)++; + } + } else + _XEatData(dpy, rep.length << 2); + } + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; +} + +SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) ( + Display *dpy, + XvPortID port, + int *num +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvListImageFormatsReq *req; + xvListImageFormatsReply rep; + SDL_NAME(XvImageFormatValues) *ret = NULL; + + *num = 0; + + XvCheckExtension(dpy, info, NULL); + + LockDisplay(dpy); + + XvGetReq(ListImageFormats, req); + req->port = port; + + /* READ THE REPLY */ + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + if(rep.num_formats) { + int size = (rep.num_formats * sizeof(SDL_NAME(XvImageFormatValues))); + + if((ret = Xmalloc(size))) { + xvImageFormatInfo Info; + int i; + + for(i = 0; i < rep.num_formats; i++) { + _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo); + ret[i].id = Info.id; + ret[i].type = Info.type; + ret[i].byte_order = Info.byte_order; + memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16); + ret[i].bits_per_pixel = Info.bpp; + ret[i].format = Info.format; + ret[i].num_planes = Info.num_planes; + ret[i].depth = Info.depth; + ret[i].red_mask = Info.red_mask; + ret[i].green_mask = Info.green_mask; + ret[i].blue_mask = Info.blue_mask; + ret[i].y_sample_bits = Info.y_sample_bits; + ret[i].u_sample_bits = Info.u_sample_bits; + ret[i].v_sample_bits = Info.v_sample_bits; + ret[i].horz_y_period = Info.horz_y_period; + ret[i].horz_u_period = Info.horz_u_period; + ret[i].horz_v_period = Info.horz_v_period; + ret[i].vert_y_period = Info.vert_y_period; + ret[i].vert_u_period = Info.vert_u_period; + ret[i].vert_v_period = Info.vert_v_period; + memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32); + ret[i].scanline_order = Info.scanline_order; + (*num)++; + } + } else + _XEatData(dpy, rep.length << 2); + } + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; +} + +SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) ( + Display *dpy, + XvPortID port, + int id, + char *data, + int width, + int height +) { + XExtDisplayInfo *info = xv_find_display(dpy); + xvQueryImageAttributesReq *req; + xvQueryImageAttributesReply rep; + SDL_NAME(XvImage) *ret = NULL; + + XvCheckExtension(dpy, info, NULL); + + LockDisplay(dpy); + + XvGetReq(QueryImageAttributes, req); + req->id = id; + req->port = port; + req->width = width; + req->height = height; + + /* READ THE REPLY */ + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + if((ret = (SDL_NAME(XvImage)*)Xmalloc(sizeof(SDL_NAME(XvImage)) + (rep.num_planes << 3)))) { + ret->id = id; + ret->width = rep.width; + ret->height = rep.height; + ret->data_size = rep.data_size; + ret->num_planes = rep.num_planes; + ret->pitches = (int*)(&ret[1]); + ret->offsets = ret->pitches + rep.num_planes; + ret->data = data; + ret->obdata = NULL; + _XRead(dpy, (char*)(ret->pitches), rep.num_planes << 2); + _XRead(dpy, (char*)(ret->offsets), rep.num_planes << 2); + } else + _XEatData(dpy, rep.length << 2); + + UnlockDisplay(dpy); + SyncHandle(); + return ret; +} + +SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) ( + Display *dpy, + XvPortID port, + int id, + char *data, + int width, + int height, + XShmSegmentInfo *shminfo +){ + SDL_NAME(XvImage) *ret; + + ret = SDL_NAME(XvCreateImage)(dpy, port, id, data, width, height); + + if(ret) ret->obdata = (XPointer)shminfo; + + return ret; +} + +int SDL_NAME(XvPutImage) ( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + SDL_NAME(XvImage) *image, + int src_x, + int src_y, + unsigned int src_w, + unsigned int src_h, + int dest_x, + int dest_y, + unsigned int dest_w, + unsigned int dest_h +){ + XExtDisplayInfo *info = xv_find_display(dpy); + xvPutImageReq *req; + int len; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(PutImage, req); + + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->id = image->id; + req->src_x = src_x; + req->src_y = src_y; + req->src_w = src_w; + req->src_h = src_h; + req->drw_x = dest_x; + req->drw_y = dest_y; + req->drw_w = dest_w; + req->drw_h = dest_h; + req->width = image->width; + req->height = image->height; + + len = (image->data_size + 3) >> 2; + SetReqLen(req, len, len); + + /* Yes it's kindof lame that we are sending the whole thing, + but for video all of it may be needed even if displaying + only a subsection, and I don't want to go through the + trouble of creating subregions to send */ + Data(dpy, (char *)image->data, image->data_size); + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + +int SDL_NAME(XvShmPutImage) ( + Display *dpy, + XvPortID port, + Drawable d, + GC gc, + SDL_NAME(XvImage) *image, + int src_x, + int src_y, + unsigned int src_w, + unsigned int src_h, + int dest_x, + int dest_y, + unsigned int dest_w, + unsigned int dest_h, + Bool send_event +){ + XExtDisplayInfo *info = xv_find_display(dpy); + XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata; + xvShmPutImageReq *req; + + XvCheckExtension(dpy, info, XvBadExtension); + + LockDisplay(dpy); + + FlushGC(dpy, gc); + + XvGetReq(ShmPutImage, req); + + req->port = port; + req->drawable = d; + req->gc = gc->gid; + req->shmseg = shminfo->shmseg; + req->id = image->id; + req->src_x = src_x; + req->src_y = src_y; + req->src_w = src_w; + req->src_h = src_h; + req->drw_x = dest_x; + req->drw_y = dest_y; + req->drw_w = dest_w; + req->drw_h = dest_h; + req->offset = image->data - shminfo->shmaddr; + req->width = image->width; + req->height = image->height; + req->send_event = send_event; + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + + +static Bool +xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = xv_find_display(dpy); + SDL_NAME(XvEvent) *re = (SDL_NAME(XvEvent) *)host; + xvEvent *event = (xvEvent *)wire; + + XvCheckExtension(dpy, info, False); + + switch((event->u.u.type & 0x7F) - info->codes->first_event) + { + case XvVideoNotify: + re->xvvideo.type = event->u.u.type & 0x7f; + re->xvvideo.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0); + re->xvvideo.display = dpy; + re->xvvideo.time = event->u.videoNotify.time; + re->xvvideo.reason = event->u.videoNotify.reason; + re->xvvideo.drawable = event->u.videoNotify.drawable; + re->xvvideo.port_id = event->u.videoNotify.port; + break; + case XvPortNotify: + re->xvport.type = event->u.u.type & 0x7f; + re->xvport.serial = + _XSetLastRequestRead(dpy, (xGenericReply *)event); + re->xvport.send_event = ((event->u.u.type & 0x80) != 0); + re->xvport.display = dpy; + re->xvport.time = event->u.portNotify.time; + re->xvport.port_id = event->u.portNotify.port; + re->xvport.attribute = event->u.portNotify.attribute; + re->xvport.value = event->u.portNotify.value; + break; + default: + return False; + } + + return (True); +} + + diff --git a/apps/plugins/sdl/src/video/Xext/Xv/Xvlibint.h b/apps/plugins/sdl/src/video/Xext/Xv/Xvlibint.h new file mode 100644 index 0000000000..20df706dc7 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xv/Xvlibint.h @@ -0,0 +1,81 @@ +/*********************************************************** +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/lib/Xv/Xvlibint.h,v 1.5 2001/07/25 15:04:53 dawes Exp $ */ + +#ifndef XVLIBINT_H +#define XVLIBINT_H +/* +** File: +** +** Xvlibint.h --- Xv library internal header file +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 01.24.91 Carver +** - version 1.4 upgrade +** +*/ + +#define NEED_REPLIES + +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif + +#include "../extensions/Xvproto.h" +#include "../extensions/Xvlib.h" + +#if !defined(UNIXCPP) +#define XvGetReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = info->codes->major_opcode;\ + req->xvReqType = xv_##name; \ + req->length = (SIZEOF(xv##name##Req))>>2;\ + dpy->bufptr += SIZEOF(xv##name##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define XvGetReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xv/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xv/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = info->codes->major_opcode;\ + req->xvReqType = xv_/**/name;\ + req->length = (SIZEOF(xv/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(xv/**/name/**/Req);\ + dpy->request++ +#endif + + +#endif /* XVLIBINT_H */ diff --git a/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA.c b/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA.c new file mode 100644 index 0000000000..fc729f1257 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA.c @@ -0,0 +1,721 @@ +/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.19 2001/08/18 02:41:30 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995,1996 The XFree86 Project, Inc + +*/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef __EMX__ /* needed here to override certain constants in X headers */ +#define INCL_DOS +#define INCL_DOSIOCTL +#include +#endif + +#if defined(linux) +#define HAS_MMAP_ANON +#include +#include +/*#include */ /* PAGE_SIZE */ +#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ +#define HAS_GETPAGESIZE +#endif /* linux */ + +#if defined(CSRG_BASED) +#define HAS_MMAP_ANON +#define HAS_GETPAGESIZE +#include +#include +#endif /* CSRG_BASED */ + +#if defined(DGUX) +#define HAS_GETPAGESIZE +#define MMAP_DEV_ZERO +#include +#include +#include +#endif /* DGUX */ + +#if defined(SVR4) && !defined(DGUX) +#define MMAP_DEV_ZERO +#include +#include +#include +#endif /* SVR4 && !DGUX */ + +#if defined(sun) && !defined(SVR4) /* SunOS */ +#define MMAP_DEV_ZERO /* doesn't SunOS have MAP_ANON ?? */ +#define HAS_GETPAGESIZE +#include +#include +#endif /* sun && !SVR4 */ + +#ifdef XNO_SYSCONF +#undef _SC_PAGESIZE +#endif + +#define NEED_EVENTS +#define NEED_REPLIES + +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif + +#include "../extensions/xf86dga.h" +#include "../extensions/xf86dgastr.h" +#include "../extensions/Xext.h" +#include "../extensions/extutil.h" + +extern XExtDisplayInfo* SDL_NAME(xdga_find_display)(Display*); +extern char *SDL_NAME(xdga_extension_name); + +#define XF86DGACheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val) + +/***************************************************************************** + * * + * public XFree86-DGA Extension routines * + * * + *****************************************************************************/ + +Bool SDL_NAME(XF86DGAQueryExtension) ( + Display *dpy, + int *event_basep, + int *error_basep +){ + return SDL_NAME(XDGAQueryExtension)(dpy, event_basep, error_basep); +} + +Bool SDL_NAME(XF86DGAQueryVersion)( + Display* dpy, + int* majorVersion, + int* minorVersion +){ + return SDL_NAME(XDGAQueryVersion)(dpy, majorVersion, minorVersion); +} + +Bool SDL_NAME(XF86DGAGetVideoLL)( + Display* dpy, + int screen, + int *offset, + int *width, + int *bank_size, + int *ram_size +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAGetVideoLLReply rep; + xXF86DGAGetVideoLLReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetVideoLL, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetVideoLL; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *offset = /*(char *)*/rep.offset; + *width = rep.width; + *bank_size = rep.bank_size; + *ram_size = rep.ram_size; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool SDL_NAME(XF86DGADirectVideoLL)( + Display* dpy, + int screen, + int enable +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGADirectVideoReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGADirectVideo, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGADirectVideo; + req->screen = screen; + req->enable = enable; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool SDL_NAME(XF86DGAGetViewPortSize)( + Display* dpy, + int screen, + int *width, + int *height +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAGetViewPortSizeReply rep; + xXF86DGAGetViewPortSizeReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetViewPortSize, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetViewPortSize; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *width = rep.width; + *height = rep.height; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool SDL_NAME(XF86DGASetViewPort)( + Display* dpy, + int screen, + int x, + int y +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGASetViewPortReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGASetViewPort, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGASetViewPort; + req->screen = screen; + req->x = x; + req->y = y; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + + +Bool SDL_NAME(XF86DGAGetVidPage)( + Display* dpy, + int screen, + int *vpage +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAGetVidPageReply rep; + xXF86DGAGetVidPageReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetVidPage, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetVidPage; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *vpage = rep.vpage; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool SDL_NAME(XF86DGASetVidPage)( + Display* dpy, + int screen, + int vpage +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGASetVidPageReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGASetVidPage, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGASetVidPage; + req->screen = screen; + req->vpage = vpage; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool SDL_NAME(XF86DGAInstallColormap)( + Display* dpy, + int screen, + Colormap cmap +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAInstallColormapReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAInstallColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAInstallColormap; + req->screen = screen; + req->id = cmap; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool SDL_NAME(XF86DGAQueryDirectVideo)( + Display *dpy, + int screen, + int *flags +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAQueryDirectVideoReply rep; + xXF86DGAQueryDirectVideoReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAQueryDirectVideo, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAQueryDirectVideo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *flags = rep.flags; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool SDL_NAME(XF86DGAViewPortChanged)( + Display *dpy, + int screen, + int n +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXF86DGAViewPortChangedReply rep; + xXF86DGAViewPortChangedReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAViewPortChanged, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAViewPortChanged; + req->screen = screen; + req->n = n; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.result; +} + + + +/* Helper functions */ + +#include +#include "../extensions/xf86dga.h" +#include +#include +#include +#if defined(ISC) +# define HAS_SVR3_MMAP +# include +# include + +# include +# include + +# include +# include +# include + +# include +#else +# if !defined(Lynx) +# if !defined(__EMX__) +# include +# endif +# else +# include +# include +# include +# endif +#endif +#include +#include +#include + +#if defined(SVR4) && !defined(sun) && !defined(SCO325) +#define DEV_MEM "/dev/pmem" +#elif defined(SVR4) && defined(sun) +#define DEV_MEM "/dev/xsvc" +#else +#define DEV_MEM "/dev/mem" +#endif + +typedef struct { + unsigned long physaddr; /* actual requested physical address */ + unsigned long size; /* actual requested map size */ + unsigned long delta; /* delta to account for page alignment */ + void * vaddr; /* mapped address, without the delta */ + int refcount; /* reference count */ +} MapRec, *MapPtr; + +typedef struct { + Display * display; + int screen; + MapPtr map; +} ScrRec, *ScrPtr; + +static int mapFd = -1; +static int numMaps = 0; +static int numScrs = 0; +static MapPtr *mapList = NULL; +static ScrPtr *scrList = NULL; + +static MapPtr +AddMap(void) +{ + MapPtr *old; + + old = mapList; + mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1)); + if (!mapList) { + mapList = old; + return NULL; + } + mapList[numMaps] = malloc(sizeof(MapRec)); + if (!mapList[numMaps]) + return NULL; + return mapList[numMaps++]; +} + +static ScrPtr +AddScr(void) +{ + ScrPtr *old; + + old = scrList; + scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1)); + if (!scrList) { + scrList = old; + return NULL; + } + scrList[numScrs] = malloc(sizeof(ScrRec)); + if (!scrList[numScrs]) + return NULL; + return scrList[numScrs++]; +} + +static MapPtr +FindMap(unsigned long address, unsigned long size) +{ + int i; + + for (i = 0; i < numMaps; i++) { + if (mapList[i]->physaddr == address && + mapList[i]->size == size) + return mapList[i]; + } + return NULL; +} + +static ScrPtr +FindScr(Display *display, int screen) +{ + int i; + + for (i = 0; i < numScrs; i++) { + if (scrList[i]->display == display && + scrList[i]->screen == screen) + return scrList[i]; + } + return NULL; +} + +static void * +MapPhysAddress(unsigned long address, unsigned long size) +{ + unsigned long offset, delta; + int pagesize = -1; + void *vaddr; + MapPtr mp; +#if defined(ISC) && defined(HAS_SVR3_MMAP) + struct kd_memloc mloc; +#elif defined(__EMX__) + APIRET rc; + ULONG action; + HFILE hfd; +#endif + + if ((mp = FindMap(address, size))) { + mp->refcount++; + return (void *)((unsigned long)mp->vaddr + mp->delta); + } + +#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE) + pagesize = sysconf(_SC_PAGESIZE); +#endif +#ifdef _SC_PAGE_SIZE + if (pagesize == -1) + pagesize = sysconf(_SC_PAGE_SIZE); +#endif +#ifdef HAS_GETPAGESIZE + if (pagesize == -1) + pagesize = getpagesize(); +#endif +#ifdef PAGE_SIZE + if (pagesize == -1) + pagesize = PAGE_SIZE; +#endif + if (pagesize == -1) + pagesize = 4096; + + delta = address % pagesize; + offset = address - delta; + +#if defined(ISC) && defined(HAS_SVR3_MMAP) + if (mapFd < 0) { + if ((mapFd = open("/dev/mmap", O_RDWR)) < 0) + return NULL; + } + mloc.vaddr = (char *)0; + mloc.physaddr = (char *)offset; + mloc.length = size + delta; + mloc.ioflg=1; + + if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1) + return NULL; +#elif defined (__EMX__) + /* + * Dragon warning here! /dev/pmap$ is never closed, except on progam exit. + * Consecutive calling of this routine will make PMAP$ driver run out + * of memory handles. Some umap/close mechanism should be provided + */ + + rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL); + if (rc != 0) + return NULL; + { + struct map_ioctl { + union { + ULONG phys; + void* user; + } a; + ULONG size; + } pmap,dmap; + ULONG plen,dlen; +#define XFREE86_PMAP 0x76 +#define PMAP_MAP 0x44 + + pmap.a.phys = offset; + pmap.size = size + delta; + rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP, + (PULONG)&pmap, sizeof(pmap), &plen, + (PULONG)&dmap, sizeof(dmap), &dlen); + if (rc == 0) { + vaddr = dmap.a.user; + } + } + if (rc != 0) + return NULL; +#elif defined (Lynx) + vaddr = (void *)smem_create("XF86DGA", (char *)offset, + size + delta, SM_READ|SM_WRITE); +#else +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + if (mapFd < 0) { + if ((mapFd = open(DEV_MEM, O_RDWR)) < 0) + return NULL; + } + vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, mapFd, (off_t)offset); + if (vaddr == (void *)-1) + return NULL; +#endif + + if (!vaddr) { + if (!(mp = AddMap())) + return NULL; + mp->physaddr = address; + mp->size = size; + mp->delta = delta; + mp->vaddr = vaddr; + mp->refcount = 1; + } + return (void *)((unsigned long)vaddr + delta); +} + +/* + * Still need to find a clean way of detecting the death of a DGA app + * and returning things to normal - Jon + * This is here to help debugging without rebooting... Also C-A-BS + * should restore text mode. + */ + +int +SDL_NAME(XF86DGAForkApp)(int screen) +{ + pid_t pid; + int status; + int i; + + /* fork the app, parent hangs around to clean up */ + if ((pid = fork()) > 0) { + ScrPtr sp; + + waitpid(pid, &status, 0); + for (i = 0; i < numScrs; i++) { + sp = scrList[i]; + SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0); + XSync(sp->display, False); + } + if (WIFEXITED(status)) + _exit(0); + else + _exit(-1); + } + return pid; +} + + +Bool +SDL_NAME(XF86DGADirectVideo)( + Display *dis, + int screen, + int enable +){ + ScrPtr sp; + MapPtr mp = NULL; + + if ((sp = FindScr(dis, screen))) + mp = sp->map; + + if (enable & XF86DGADirectGraphics) { +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ + && !defined(__EMX__) + if (mp && mp->vaddr) + mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE); +#endif + } else { +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ + && !defined(__EMX__) + if (mp && mp->vaddr) + mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ); +#elif defined(Lynx) + /* XXX this doesn't allow enable after disable */ + smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH); + smem_remove("XF86DGA"); +#endif + } + + SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable); + return 1; +} + + +static void +XF86cleanup(int sig) +{ + ScrPtr sp; + int i; + static char beenhere = 0; + + if (beenhere) + _exit(3); + beenhere = 1; + + for (i = 0; i < numScrs; i++) { + sp = scrList[i]; + SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0); + XSync(sp->display, False); + } + _exit(3); +} + +Bool +SDL_NAME(XF86DGAGetVideo)( + Display *dis, + int screen, + char **addr, + int *width, + int *bank, + int *ram +){ + /*unsigned long*/ int offset; + static int beenHere = 0; + ScrPtr sp; + MapPtr mp; + + if (!(sp = FindScr(dis, screen))) { + if (!(sp = AddScr())) { + fprintf(stderr, "XF86DGAGetVideo: malloc failure\n"); + exit(-2); + } + sp->display = dis; + sp->screen = screen; + sp->map = NULL; + } + + SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram); + + *addr = MapPhysAddress(offset, *bank); + if (*addr == NULL) { + fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n", + strerror(errno)); + exit(-2); + } + + if ((mp = FindMap(offset, *bank))) + sp->map = mp; + + if (!beenHere) { + beenHere = 1; + atexit((void(*)(void))XF86cleanup); + /* one shot XF86cleanup attempts */ + signal(SIGSEGV, XF86cleanup); +#ifdef SIGBUS + signal(SIGBUS, XF86cleanup); +#endif + signal(SIGHUP, XF86cleanup); + signal(SIGFPE, XF86cleanup); + } + + return 1; +} + diff --git a/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA2.c b/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA2.c new file mode 100644 index 0000000000..11d4fddc6a --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xxf86dga/XF86DGA2.c @@ -0,0 +1,993 @@ +/* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995,1996 The XFree86 Project, Inc + +*/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef __EMX__ /* needed here to override certain constants in X headers */ +#define INCL_DOS +#define INCL_DOSIOCTL +#include +#endif + +#define NEED_EVENTS +#define NEED_REPLIES + +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif + +#include "../extensions/xf86dga.h" +#include "../extensions/xf86dgastr.h" +#include "../extensions/Xext.h" +#include "../extensions/extutil.h" +#include + +#if defined(ENABLE_FBCON) /* Needed for framebuffer console support */ +#include +#include +#endif + +/* If you change this, change the Bases[] array below as well */ +#define MAX_HEADS 16 + +char *SDL_NAME(xdga_extension_name) = XF86DGANAME; + +static XExtensionInfo _xdga_info_data; +static XExtensionInfo *xdga_info = &_xdga_info_data; + + +Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32); +void SDL_NAME(XDGAUnmapFramebuffer)(int); +unsigned char* SDL_NAME(XDGAGetMappedMemory)(int); + +#define XDGACheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int xdga_close_display(Display *dpy, XExtCodes *codes); +static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev); +static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev); + +static XExtensionHooks xdga_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + xdga_close_display, /* close_display */ + xdga_wire_to_event, /* wire_to_event */ + xdga_event_to_wire, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info) + + +XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info, + "XFree86-DGA", + &xdga_extension_hooks, + 0, NULL) + + +static Status +xdga_event_to_wire( + Display *dpy, + XEvent *event, + xEvent *wire_ev +){ + return True; +} + +static Bool +xdga_wire_to_event( + Display *dpy, + XEvent *event, + xEvent *wire_ev +){ + dgaEvent *wire = (dgaEvent *) wire_ev; + SDL_NAME(XDGAButtonEvent) *bevent; + SDL_NAME(XDGAKeyEvent) *kevent; + SDL_NAME(XDGAMotionEvent) *mevent; + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + + XDGACheckExtension (dpy, info, False); + + switch((wire->u.u.type & 0x7f) - info->codes->first_event) { + case MotionNotify: + mevent = (SDL_NAME(XDGAMotionEvent)*)event; + mevent->type = wire->u.u.type & 0x7F; + mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + mevent->display = dpy; + mevent->screen = wire->u.event.screen; + mevent->time = wire->u.event.time; + mevent->state = wire->u.event.state; + mevent->dx = wire->u.event.dx; + mevent->dy = wire->u.event.dy; + return True; + case ButtonPress: + case ButtonRelease: + bevent = (SDL_NAME(XDGAButtonEvent)*)event; + bevent->type = wire->u.u.type & 0x7F; + bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + bevent->display = dpy; + bevent->screen = wire->u.event.screen; + bevent->time = wire->u.event.time; + bevent->state = wire->u.event.state; + bevent->button = wire->u.u.detail; + return True; + case KeyPress: + case KeyRelease: + kevent = (SDL_NAME(XDGAKeyEvent)*)event; + kevent->type = wire->u.u.type & 0x7F; + kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + kevent->display = dpy; + kevent->screen = wire->u.event.screen; + kevent->time = wire->u.event.time; + kevent->state = wire->u.event.state; + kevent->keycode = wire->u.u.detail; + return True; + } + + return False; +} + + +Bool SDL_NAME(XDGAQueryExtension) ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Bool SDL_NAME(XDGAQueryVersion)( + Display *dpy, + int *majorVersion, + int *minorVersion +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAQueryVersionReply rep; + xXDGAQueryVersionReq *req; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGAQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + if (*majorVersion >= 2) + { + int i, j; + + for (i = 0, j = info->codes->first_event; + i < XF86DGANumberEvents; + i++, j++) + { + XESetWireToEvent(dpy, j, xdga_wire_to_event); + XESetEventToWire(dpy, j, xdga_event_to_wire); + } + SDL_NAME(XDGASetClientVersion)(dpy); + } + return True; +} + +Bool SDL_NAME(XDGASetClientVersion)( + Display *dpy +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGASetClientVersionReq *req; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGASetClientVersion, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASetClientVersion; + req->major = XDGA_MAJOR_VERSION; + req->minor = XDGA_MINOR_VERSION; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool SDL_NAME(XDGAOpenFramebuffer)( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAOpenFramebufferReply rep; + xXDGAOpenFramebufferReq *req; + char *deviceName = NULL; + Bool ret; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGAOpenFramebuffer, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAOpenFramebuffer; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + if(rep.length) { + deviceName = Xmalloc(rep.length << 2); + _XRead(dpy, deviceName, rep.length << 2); + } + + ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName, + (unsigned char*)(long)rep.mem1, + rep.size, rep.offset, rep.extra); + + if(deviceName) + Xfree(deviceName); + + UnlockDisplay(dpy); + SyncHandle(); + return ret; +} + +void SDL_NAME(XDGACloseFramebuffer)( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGACloseFramebufferReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + SDL_NAME(XDGAUnmapFramebuffer)(screen); + + LockDisplay(dpy); + GetReq(XDGACloseFramebuffer, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACloseFramebuffer; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); +} + + + +SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)( + Display *dpy, + int screen, + int *num +){ + XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy); + xXDGAQueryModesReply rep; + xXDGAQueryModesReq *req; + SDL_NAME(XDGAMode) *modes = NULL; + + *num = 0; + + XDGACheckExtension (dpy, dinfo, NULL); + + LockDisplay(dpy); + GetReq(XDGAQueryModes, req); + req->reqType = dinfo->codes->major_opcode; + req->dgaReqType = X_XDGAQueryModes; + req->screen = screen; + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + if(rep.length) { + xXDGAModeInfo info; + int i, size; + char *offset; + + size = rep.length << 2; + size -= rep.number * sz_xXDGAModeInfo; /* find text size */ + modes = (SDL_NAME(XDGAMode)*)Xmalloc((rep.number * sizeof(SDL_NAME(XDGAMode))) + size); + offset = (char*)(&modes[rep.number]); /* start of text */ + + + if(modes) { + for(i = 0; i < rep.number; i++) { + _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); + + modes[i].num = info.num; + modes[i].verticalRefresh = + (float)info.vsync_num / (float)info.vsync_den; + modes[i].flags = info.flags; + modes[i].imageWidth = info.image_width; + modes[i].imageHeight = info.image_height; + modes[i].pixmapWidth = info.pixmap_width; + modes[i].pixmapHeight = info.pixmap_height; + modes[i].bytesPerScanline = info.bytes_per_scanline; + modes[i].byteOrder = info.byte_order; + modes[i].depth = info.depth; + modes[i].bitsPerPixel = info.bpp; + modes[i].redMask = info.red_mask; + modes[i].greenMask = info.green_mask; + modes[i].blueMask = info.blue_mask; + modes[i].visualClass = info.visual_class; + modes[i].viewportWidth = info.viewport_width; + modes[i].viewportHeight = info.viewport_height; + modes[i].xViewportStep = info.viewport_xstep; + modes[i].yViewportStep = info.viewport_ystep; + modes[i].maxViewportX = info.viewport_xmax; + modes[i].maxViewportY = info.viewport_ymax; + modes[i].viewportFlags = info.viewport_flags; + modes[i].reserved1 = info.reserved1; + modes[i].reserved2 = info.reserved2; + + _XRead(dpy, offset, info.name_size); + modes[i].name = offset; + offset += info.name_size; + } + *num = rep.number; + } else + _XEatData(dpy, rep.length << 2); + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + return modes; +} + + +SDL_NAME(XDGADevice) * +SDL_NAME(XDGASetMode)( + Display *dpy, + int screen, + int mode +){ + XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy); + xXDGASetModeReply rep; + xXDGASetModeReq *req; + SDL_NAME(XDGADevice) *dev = NULL; + Pixmap pid; + + XDGACheckExtension (dpy, dinfo, NULL); + + LockDisplay(dpy); + GetReq(XDGASetMode, req); + req->reqType = dinfo->codes->major_opcode; + req->dgaReqType = X_XDGASetMode; + req->screen = screen; + req->mode = mode; + req->pid = pid = XAllocID(dpy); + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + if(rep.length) { + xXDGAModeInfo info; + int size; + + size = rep.length << 2; + size -= sz_xXDGAModeInfo; /* get text size */ + + dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size); + + if(dev) { + _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); + + dev->mode.num = info.num; + dev->mode.verticalRefresh = + (float)info.vsync_num / (float)info.vsync_den; + dev->mode.flags = info.flags; + dev->mode.imageWidth = info.image_width; + dev->mode.imageHeight = info.image_height; + dev->mode.pixmapWidth = info.pixmap_width; + dev->mode.pixmapHeight = info.pixmap_height; + dev->mode.bytesPerScanline = info.bytes_per_scanline; + dev->mode.byteOrder = info.byte_order; + dev->mode.depth = info.depth; + dev->mode.bitsPerPixel = info.bpp; + dev->mode.redMask = info.red_mask; + dev->mode.greenMask = info.green_mask; + dev->mode.blueMask = info.blue_mask; + dev->mode.visualClass = info.visual_class; + dev->mode.viewportWidth = info.viewport_width; + dev->mode.viewportHeight = info.viewport_height; + dev->mode.xViewportStep = info.viewport_xstep; + dev->mode.yViewportStep = info.viewport_ystep; + dev->mode.maxViewportX = info.viewport_xmax; + dev->mode.maxViewportY = info.viewport_ymax; + dev->mode.viewportFlags = info.viewport_flags; + dev->mode.reserved1 = info.reserved1; + dev->mode.reserved2 = info.reserved2; + + dev->mode.name = (char*)(&dev[1]); + _XRead(dpy, dev->mode.name, info.name_size); + + dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0; + dev->data = SDL_NAME(XDGAGetMappedMemory)(screen); + + if(dev->data) + dev->data += rep.offset; + } + /* not sure what to do if the allocation fails */ + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + return dev; +} + + +void SDL_NAME(XDGASetViewport)( + Display *dpy, + int screen, + int x, + int y, + int flags +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGASetViewportReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGASetViewport, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASetViewport; + req->screen = screen; + req->x = x; + req->y = y; + req->flags = flags; + UnlockDisplay(dpy); + SyncHandle(); +} + + +void SDL_NAME(XDGAInstallColormap)( + Display *dpy, + int screen, + Colormap cmap +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAInstallColormapReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGAInstallColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAInstallColormap; + req->screen = screen; + req->cmap = cmap; + UnlockDisplay(dpy); + SyncHandle(); +} + +void SDL_NAME(XDGASelectInput)( + Display *dpy, + int screen, + long mask +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGASelectInputReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGASelectInput, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASelectInput; + req->screen = screen; + req->mask = mask; + UnlockDisplay(dpy); + SyncHandle(); +} + +void SDL_NAME(XDGAFillRectangle)( + Display *dpy, + int screen, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned long color +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAFillRectangleReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGAFillRectangle, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAFillRectangle; + req->screen = screen; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->color = color; + UnlockDisplay(dpy); + SyncHandle(); +} + +void SDL_NAME(XDGACopyArea)( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGACopyAreaReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGACopyArea, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACopyArea; + req->screen = screen; + req->srcx = srcx; + req->srcy = srcy; + req->width = width; + req->height = height; + req->dstx = dstx; + req->dsty = dsty; + UnlockDisplay(dpy); + SyncHandle(); +} + +void SDL_NAME(XDGACopyTransparentArea)( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty, + unsigned long key +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGACopyTransparentAreaReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGACopyTransparentArea, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACopyTransparentArea; + req->screen = screen; + req->srcx = srcx; + req->srcy = srcy; + req->width = width; + req->height = height; + req->dstx = dstx; + req->dsty = dsty; + req->key = key; + UnlockDisplay(dpy); + SyncHandle(); +} + + +int SDL_NAME(XDGAGetViewportStatus)( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAGetViewportStatusReply rep; + xXDGAGetViewportStatusReq *req; + int status = 0; + + XDGACheckExtension (dpy, info, 0); + + LockDisplay(dpy); + GetReq(XDGAGetViewportStatus, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAGetViewportStatus; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) + status = rep.status; + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +void SDL_NAME(XDGASync)( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGASyncReply rep; + xXDGASyncReq *req; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGASync, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASync; + req->screen = screen; + _XReply(dpy, (xReply *)&rep, 0, xFalse); + UnlockDisplay(dpy); + SyncHandle(); +} + + +void SDL_NAME(XDGAChangePixmapMode)( + Display *dpy, + int screen, + int *x, + int *y, + int mode +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGAChangePixmapModeReq *req; + xXDGAChangePixmapModeReply rep; + + XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name)); + + LockDisplay(dpy); + GetReq(XDGAChangePixmapMode, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAChangePixmapMode; + req->screen = screen; + req->x = *x; + req->y = *y; + req->flags = mode; + _XReply(dpy, (xReply *)&rep, 0, xFalse); + *x = rep.x; + *y = rep.y; + UnlockDisplay(dpy); + SyncHandle(); +} + +Colormap SDL_NAME(XDGACreateColormap)( + Display *dpy, + int screen, + SDL_NAME(XDGADevice) *dev, + int alloc +){ + XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy); + xXDGACreateColormapReq *req; + Colormap cid; + + XDGACheckExtension (dpy, info, -1); + + LockDisplay(dpy); + GetReq(XDGACreateColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACreateColormap; + req->screen = screen; + req->mode = dev->mode.num; + req->alloc = alloc; + cid = req->id = XAllocID(dpy); + UnlockDisplay(dpy); + SyncHandle(); + + return cid; +} + + +void SDL_NAME(XDGAKeyEventToXKeyEvent)( + SDL_NAME(XDGAKeyEvent)* dk, + XKeyEvent* xk +){ + xk->type = dk->type; + xk->serial = dk->serial; + xk->send_event = False; + xk->display = dk->display; + xk->window = RootWindow(dk->display, dk->screen); + xk->root = xk->window; + xk->subwindow = None; + xk->time = dk->time; + xk->x = xk->y = xk->x_root = xk->y_root = 0; + xk->state = dk->state; + xk->keycode = dk->keycode; + xk->same_screen = True; +} + +#include +#include +#include +#include +#if defined(ISC) +# define HAS_SVR3_MMAP +# include +# include + +# include +# include + +# include +# include +# include + +# include +#else +# if !defined(Lynx) +# if !defined(__EMX__) +# include +# endif +# else +# include +# include +# include +# endif +#endif +#include +#include +#include + +#if defined(SVR4) && !defined(sun) && !defined(SCO325) +#define DEV_MEM "/dev/pmem" +#elif defined(SVR4) && defined(sun) +#define DEV_MEM "/dev/xsvc" +#else +#define DEV_MEM "/dev/mem" +#endif + + + +typedef struct _DGAMapRec{ + unsigned char *physical; + unsigned char *virtual; + CARD32 size; + int fd; + int screen; + struct _DGAMapRec *next; +} DGAMapRec, *DGAMapPtr; + +static Bool +DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr); +static void DGAUnmapPhysical(DGAMapPtr); + +static DGAMapPtr _Maps = NULL; + + +unsigned char* +SDL_NAME(XDGAGetMappedMemory)(int screen) +{ + DGAMapPtr pMap = _Maps; + unsigned char *pntr = NULL; + + while(pMap != NULL) { + if(pMap->screen == screen) { + pntr = pMap->virtual; + break; + } + pMap = pMap->next; + } + + return pntr; +} + +Bool +SDL_NAME(XDGAMapFramebuffer)( + int screen, + char *name, /* optional device name */ + unsigned char* base, /* physical memory */ + CARD32 size, /* size */ + CARD32 offset, /* optional offset */ + CARD32 extra /* optional extra data */ +){ + DGAMapPtr pMap = _Maps; + Bool result; + + /* is it already mapped ? */ + while(pMap != NULL) { + if(pMap->screen == screen) + return True; + pMap = pMap->next; + } + + if(extra & XDGANeedRoot) { + /* we should probably check if we have root permissions and + return False here */ + + } + + pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec)); + + result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap); + + if(result) { + pMap->next = _Maps; + _Maps = pMap; + } else + Xfree(pMap); + + return result; +} + +void +SDL_NAME(XDGAUnmapFramebuffer)(int screen) +{ + DGAMapPtr pMap = _Maps; + DGAMapPtr pPrev = NULL; + + /* is it already mapped */ + while(pMap != NULL) { + if(pMap->screen == screen) + break; + pPrev = pMap; + pMap = pMap->next; + } + + if(!pMap) + return; + + DGAUnmapPhysical(pMap); + + if(!pPrev) + _Maps = pMap->next; + else + pPrev->next = pMap->next; + + Xfree(pMap); +} + + +static Bool +DGAMapPhysical( + int screen, + char *name, /* optional device name */ + unsigned char* base, /* physical memory */ + CARD32 size, /* size */ + CARD32 offset, /* optional offset */ + CARD32 extra, /* optional extra data */ + DGAMapPtr pMap +) { +#if defined(ISC) && defined(HAS_SVR3_MMAP) + struct kd_memloc mloc; +#elif defined(__EMX__) + APIRET rc; + ULONG action; + HFILE hfd; +#endif + + base += offset; + + pMap->screen = screen; + pMap->physical = base; + pMap->size = size; + +#if defined(ISC) && defined(HAS_SVR3_MMAP) + if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0) + return False; + mloc.vaddr = (char *)0; + mloc.physaddr = (char *)base; + mloc.length = size; + mloc.ioflg=1; + + if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1) + return False; +#elif defined (__EMX__) + /* + * Dragon warning here! /dev/pmap$ is never closed, except on progam exit. + * Consecutive calling of this routine will make PMAP$ driver run out + * of memory handles. Some umap/close mechanism should be provided + */ + + rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL); + if (rc != 0) + return False; + { + struct map_ioctl { + union { + ULONG phys; + void* user; + } a; + ULONG size; + } pmap,dmap; + ULONG plen,dlen; +#define XFREE86_PMAP 0x76 +#define PMAP_MAP 0x44 + + pmap.a.phys = base; + pmap.size = size; + rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP, + (PULONG)&pmap, sizeof(pmap), &plen, + (PULONG)&dmap, sizeof(dmap), &dlen); + if (rc == 0) { + pMap->virtual = dmap.a.user; + } + } + if (rc != 0) + return False; +#elif defined (Lynx) + pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE); +#else +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + if (!name) + name = DEV_MEM; + if ((pMap->fd = open(name, O_RDWR)) < 0) +#if defined(ENABLE_FBCON) + { /* /dev/fb0 fallback added by Sam Lantinga */ + /* Try to fall back to /dev/fb on Linux - FIXME: verify the device */ + struct fb_fix_screeninfo finfo; + + if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) { + return False; + } + /* The useable framebuffer console memory may not be the whole + framebuffer that X has access to. :-( + */ + if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { + close(pMap->fd); + return False; + } + /* Warning: On PPC, the size and virtual need to be offset by: + (((long)finfo.smem_start) - + (((long)finfo.smem_start)&~(PAGE_SIZE-1))) + */ + base = 0; + size = pMap->size = finfo.smem_len; + } +#else + return False; +#endif + pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, pMap->fd, (off_t)((size_t)base)); + if (pMap->virtual == (void *)-1) + return False; +#endif + +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ + && !defined(__EMX__) + mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE); +#endif + + return True; +} + + + +static void +DGAUnmapPhysical(DGAMapPtr pMap) +{ +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ + && !defined(__EMX__) + mprotect(pMap->virtual,pMap->size, PROT_READ); +#elif defined(Lynx) + /* XXX this doesn't allow enable after disable */ + smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH); + smem_remove("XF86DGA"); +#endif + + + /* We need to unmap and close too !!!!!!!!!!*/ +} diff --git a/apps/plugins/sdl/src/video/Xext/Xxf86vm/XF86VMode.c b/apps/plugins/sdl/src/video/Xext/Xxf86vm/XF86VMode.c new file mode 100644 index 0000000000..5cb21905af --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/Xxf86vm/XF86VMode.c @@ -0,0 +1,1226 @@ +/* $XConsortium: XF86VMode.c /main/2 1995/11/14 18:17:58 kaleb $ */ +/* $XFree86: xc/lib/Xxf86vm/XF86VMode.c,v 3.32 2001/07/25 15:04:54 dawes Exp $ */ +/* + +Copyright (c) 1995 Kaleb S. KEITHLEY + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Kaleb S. KEITHLEY +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +from Kaleb S. KEITHLEY. + +*/ +/* $XConsortium: XF86VMode.c /main/4 1996/01/16 07:52:25 kaleb CHECKEDOUT $ */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_EVENTS +#define NEED_REPLIES + +#ifndef XBUILD_IN_CLIENT +/* Apparently some X11 systems can't include this multiple times... */ +#ifndef SDL_INCLUDED_XLIBINT_H +#define SDL_INCLUDED_XLIBINT_H 1 +#include +#endif +#include "../extensions/xf86vmstr.h" +#include "../extensions/Xext.h" +#include "../extensions/extutil.h" +#else +#include "include/extensions/xf86vmstr.h" +#include "include/extensions/Xext.h" +#include "include/extensions/extutil.h" +#endif + +#ifdef DEBUG +#include +#endif + +#ifndef MODE_BAD +#define MODE_BAD 255 +#endif + +static XExtensionInfo _xf86vidmode_info_data; +static XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data; +static char *xf86vidmode_extension_name = XF86VIDMODENAME; + +#define XF86VidModeCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86vidmode_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static XEXT_CLOSE_DISPLAY_PROTO(close_display); +static /* const */ XExtensionHooks xf86vidmode_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info, + xf86vidmode_extension_name, + &xf86vidmode_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info) + + +/***************************************************************************** + * * + * public XFree86-VidMode Extension routines * + * * + *****************************************************************************/ + +Bool +SDL_NAME(XF86VidModeQueryExtension) (dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + +Bool +SDL_NAME(XF86VidModeQueryVersion)(dpy, majorVersion, minorVersion) + Display* dpy; + int* majorVersion; + int* minorVersion; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeQueryVersionReply rep; + xXF86VidModeQueryVersionReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + if (*majorVersion >= 2) + SDL_NAME(XF86VidModeSetClientVersion)(dpy); + return True; +} + +Bool +SDL_NAME(XF86VidModeSetClientVersion)(Display *dpy) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86VidModeSetClientVersionReq *req; + + XF86VidModeCheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeSetClientVersion, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSetClientVersion; + req->major = XF86VIDMODE_MAJOR_VERSION; + req->minor = XF86VIDMODE_MINOR_VERSION; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeSetGamma)(Display *dpy, int screen, SDL_NAME(XF86VidModeGamma) *Gamma) +{ + XExtDisplayInfo *info = find_display(dpy); + xXF86VidModeSetGammaReq *req; + + XF86VidModeCheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeSetGamma, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSetGamma; + req->screen = screen; + req->red = (CARD32)(Gamma->red * 10000.); + req->green = (CARD32)(Gamma->green * 10000.); + req->blue = (CARD32)(Gamma->blue * 10000.); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetGamma)(Display *dpy, int screen, SDL_NAME(XF86VidModeGamma) *Gamma) +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetGammaReply rep; + xXF86VidModeGetGammaReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeGetGamma, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetGamma; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + Gamma->red = ((float)rep.red) / 10000.; + Gamma->green = ((float)rep.green) / 10000.; + Gamma->blue = ((float)rep.blue) / 10000.; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetModeLine)(dpy, screen, dotclock, modeline) + Display* dpy; + int screen; + int* dotclock; + SDL_NAME(XF86VidModeModeLine)* modeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetModeLineReply rep; + xXF86OldVidModeGetModeLineReply oldrep; + xXF86VidModeGetModeLineReq *req; + int majorVersion, minorVersion; + + XF86VidModeCheckExtension (dpy, info, False); + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + + LockDisplay(dpy); + GetReq(XF86VidModeGetModeLine, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetModeLine; + req->screen = screen; + + if (majorVersion < 2) { + if (!_XReply(dpy, (xReply *)&oldrep, + (SIZEOF(xXF86OldVidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *dotclock = oldrep.dotclock; + modeline->hdisplay = oldrep.hdisplay; + modeline->hsyncstart = oldrep.hsyncstart; + modeline->hsyncend = oldrep.hsyncend; + modeline->htotal = oldrep.htotal; + modeline->hskew = 0; + modeline->vdisplay = oldrep.vdisplay; + modeline->vsyncstart = oldrep.vsyncstart; + modeline->vsyncend = oldrep.vsyncend; + modeline->vtotal = oldrep.vtotal; + modeline->flags = oldrep.flags; + modeline->privsize = oldrep.privsize; + } else { + if (!_XReply(dpy, (xReply *)&rep, + (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *dotclock = rep.dotclock; + modeline->hdisplay = rep.hdisplay; + modeline->hsyncstart = rep.hsyncstart; + modeline->hsyncend = rep.hsyncend; + modeline->htotal = rep.htotal; + modeline->hskew = rep.hskew; + modeline->vdisplay = rep.vdisplay; + modeline->vsyncstart = rep.vsyncstart; + modeline->vsyncend = rep.vsyncend; + modeline->vtotal = rep.vtotal; + modeline->flags = rep.flags; + modeline->privsize = rep.privsize; + } + + if (modeline->privsize > 0) { + if (!(modeline->private = Xcalloc(modeline->privsize, sizeof(INT32)))) { + _XEatData(dpy, (modeline->privsize) * sizeof(INT32)); + Xfree(modeline->private); + return False; + } + _XRead(dpy, (char*)modeline->private, modeline->privsize * sizeof(INT32)); + } else { + modeline->private = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetAllModeLines)(dpy, screen, modecount, modelinesPtr) + Display* dpy; + int screen; + int* modecount; + SDL_NAME(XF86VidModeModeInfo) ***modelinesPtr; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetAllModeLinesReply rep; + xXF86VidModeGetAllModeLinesReq *req; + SDL_NAME(XF86VidModeModeInfo) *mdinfptr, **modelines; + xXF86VidModeModeInfo xmdline; + xXF86OldVidModeModeInfo oldxmdline; + int i; + int majorVersion, minorVersion; + Bool protocolBug = False; + + XF86VidModeCheckExtension (dpy, info, False); + + /* + * Note: There was a bug in the protocol implementation in versions + * 0.x with x < 8 (the .private field wasn't being passed over the wire). + * Check the server's version, and accept the old format if appropriate. + */ + + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + if (majorVersion == 0 && minorVersion < 8) { + protocolBug = True; +#ifdef DEBUG + fprintf(stderr, "XF86VidModeGetAllModeLines: Warning: Xserver is" + "running an old version (%d.%d)\n", majorVersion, + minorVersion); +#endif + } + + LockDisplay(dpy); + GetReq(XF86VidModeGetAllModeLines, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetAllModeLines; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, + (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *modecount = rep.modecount; + + if (!(modelines = (SDL_NAME(XF86VidModeModeInfo) **) Xcalloc(rep.modecount, + sizeof(SDL_NAME(XF86VidModeModeInfo) *) + +sizeof(SDL_NAME(XF86VidModeModeInfo))))) { + if (majorVersion < 2) + _XEatData(dpy, (rep.modecount) * sizeof(xXF86OldVidModeModeInfo)); + else + _XEatData(dpy, (rep.modecount) * sizeof(xXF86VidModeModeInfo)); + Xfree(modelines); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + mdinfptr = (SDL_NAME(XF86VidModeModeInfo) *) ( + (char *) modelines + + rep.modecount*sizeof(SDL_NAME(XF86VidModeModeInfo) *) + ); + + for (i = 0; i < rep.modecount; i++) { + modelines[i] = mdinfptr++; + if (majorVersion < 2) { + _XRead(dpy, (char*)&oldxmdline, sizeof(xXF86OldVidModeModeInfo)); + modelines[i]->dotclock = oldxmdline.dotclock; + modelines[i]->hdisplay = oldxmdline.hdisplay; + modelines[i]->hsyncstart = oldxmdline.hsyncstart; + modelines[i]->hsyncend = oldxmdline.hsyncend; + modelines[i]->htotal = oldxmdline.htotal; + modelines[i]->hskew = 0; + modelines[i]->vdisplay = oldxmdline.vdisplay; + modelines[i]->vsyncstart = oldxmdline.vsyncstart; + modelines[i]->vsyncend = oldxmdline.vsyncend; + modelines[i]->vtotal = oldxmdline.vtotal; + modelines[i]->flags = oldxmdline.flags; + if (protocolBug) { + modelines[i]->privsize = 0; + modelines[i]->private = NULL; + } else { + modelines[i]->privsize = oldxmdline.privsize; + if (oldxmdline.privsize > 0) { + if (!(modelines[i]->private = + Xcalloc(oldxmdline.privsize, sizeof(INT32)))) { + _XEatData(dpy, (oldxmdline.privsize) * sizeof(INT32)); + Xfree(modelines[i]->private); + } else { + _XRead(dpy, (char*)modelines[i]->private, + oldxmdline.privsize * sizeof(INT32)); + } + } else { + modelines[i]->private = NULL; + } + } + } else { + _XRead(dpy, (char*)&xmdline, sizeof(xXF86VidModeModeInfo)); + modelines[i]->dotclock = xmdline.dotclock; + modelines[i]->hdisplay = xmdline.hdisplay; + modelines[i]->hsyncstart = xmdline.hsyncstart; + modelines[i]->hsyncend = xmdline.hsyncend; + modelines[i]->htotal = xmdline.htotal; + modelines[i]->hskew = xmdline.hskew; + modelines[i]->vdisplay = xmdline.vdisplay; + modelines[i]->vsyncstart = xmdline.vsyncstart; + modelines[i]->vsyncend = xmdline.vsyncend; + modelines[i]->vtotal = xmdline.vtotal; + modelines[i]->flags = xmdline.flags; + if (protocolBug) { + modelines[i]->privsize = 0; + modelines[i]->private = NULL; + } else { + modelines[i]->privsize = xmdline.privsize; + if (xmdline.privsize > 0) { + if (!(modelines[i]->private = + Xcalloc(xmdline.privsize, sizeof(INT32)))) { + _XEatData(dpy, (xmdline.privsize) * sizeof(INT32)); + Xfree(modelines[i]->private); + } else { + _XRead(dpy, (char*)modelines[i]->private, + xmdline.privsize * sizeof(INT32)); + } + } else { + modelines[i]->private = NULL; + } + } + } + } + *modelinesPtr = modelines; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +/* + * GetReq replacement for use with VidMode protocols earlier than 2.0 + */ +#if !defined(UNIXCPP) || defined(ANSICPP) +#define GetOldReq(name, oldname, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##oldname##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##oldname##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = (SIZEOF(x##oldname##Req))>>2;\ + dpy->bufptr += SIZEOF(x##oldname##Req);\ + dpy->request++ + +#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ +#define GetOldReq(name, oldname, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/oldname/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/oldname/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = (SIZEOF(x/**/oldname/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/oldname/**/Req);\ + dpy->request++ +#endif + +Bool +SDL_NAME(XF86VidModeAddModeLine) (dpy, screen, newmodeline, aftermodeline) + Display *dpy; + int screen; + SDL_NAME(XF86VidModeModeInfo)* newmodeline; + SDL_NAME(XF86VidModeModeInfo)* aftermodeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeAddModeLineReq *req; + xXF86OldVidModeAddModeLineReq *oldreq; + int majorVersion, minorVersion; + + XF86VidModeCheckExtension (dpy, info, False); + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + + LockDisplay(dpy); + if (majorVersion < 2) { + GetOldReq(XF86VidModeAddModeLine, XF86OldVidModeAddModeLine, oldreq); + oldreq->reqType = info->codes->major_opcode; + oldreq->xf86vidmodeReqType = X_XF86VidModeAddModeLine; + oldreq->screen = screen; + oldreq->dotclock = newmodeline->dotclock; + oldreq->hdisplay = newmodeline->hdisplay; + oldreq->hsyncstart = newmodeline->hsyncstart; + oldreq->hsyncend = newmodeline->hsyncend; + oldreq->htotal = newmodeline->htotal; + oldreq->vdisplay = newmodeline->vdisplay; + oldreq->vsyncstart = newmodeline->vsyncstart; + oldreq->vsyncend = newmodeline->vsyncend; + oldreq->vtotal = newmodeline->vtotal; + oldreq->flags = newmodeline->flags; + oldreq->privsize = newmodeline->privsize; + if (aftermodeline != NULL) { + oldreq->after_dotclock = aftermodeline->dotclock; + oldreq->after_hdisplay = aftermodeline->hdisplay; + oldreq->after_hsyncstart = aftermodeline->hsyncstart; + oldreq->after_hsyncend = aftermodeline->hsyncend; + oldreq->after_htotal = aftermodeline->htotal; + oldreq->after_vdisplay = aftermodeline->vdisplay; + oldreq->after_vsyncstart = aftermodeline->vsyncstart; + oldreq->after_vsyncend = aftermodeline->vsyncend; + oldreq->after_vtotal = aftermodeline->vtotal; + oldreq->after_flags = aftermodeline->flags; + } else { + oldreq->after_dotclock = 0; + oldreq->after_hdisplay = 0; + oldreq->after_hsyncstart = 0; + oldreq->after_hsyncend = 0; + oldreq->after_htotal = 0; + oldreq->after_vdisplay = 0; + oldreq->after_vsyncstart = 0; + oldreq->after_vsyncend = 0; + oldreq->after_vtotal = 0; + oldreq->after_flags = 0; + } + if (newmodeline->privsize) { + oldreq->length += newmodeline->privsize; + Data32(dpy, (long *) newmodeline->private, + newmodeline->privsize * sizeof(INT32)); + } + } else { + GetReq(XF86VidModeAddModeLine, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeAddModeLine; + req->screen = screen; + req->dotclock = newmodeline->dotclock; + req->hdisplay = newmodeline->hdisplay; + req->hsyncstart = newmodeline->hsyncstart; + req->hsyncend = newmodeline->hsyncend; + req->htotal = newmodeline->htotal; + req->hskew = newmodeline->hskew; + req->vdisplay = newmodeline->vdisplay; + req->vsyncstart = newmodeline->vsyncstart; + req->vsyncend = newmodeline->vsyncend; + req->vtotal = newmodeline->vtotal; + req->flags = newmodeline->flags; + req->privsize = newmodeline->privsize; + if (aftermodeline != NULL) { + req->after_dotclock = aftermodeline->dotclock; + req->after_hdisplay = aftermodeline->hdisplay; + req->after_hsyncstart = aftermodeline->hsyncstart; + req->after_hsyncend = aftermodeline->hsyncend; + req->after_htotal = aftermodeline->htotal; + req->after_hskew = aftermodeline->hskew; + req->after_vdisplay = aftermodeline->vdisplay; + req->after_vsyncstart = aftermodeline->vsyncstart; + req->after_vsyncend = aftermodeline->vsyncend; + req->after_vtotal = aftermodeline->vtotal; + req->after_flags = aftermodeline->flags; + } else { + req->after_dotclock = 0; + req->after_hdisplay = 0; + req->after_hsyncstart = 0; + req->after_hsyncend = 0; + req->after_htotal = 0; + req->after_hskew = 0; + req->after_vdisplay = 0; + req->after_vsyncstart = 0; + req->after_vsyncend = 0; + req->after_vtotal = 0; + req->after_flags = 0; + } + if (newmodeline->privsize) { + req->length += newmodeline->privsize; + Data32(dpy, (long *) newmodeline->private, + newmodeline->privsize * sizeof(INT32)); + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeDeleteModeLine) (dpy, screen, modeline) + Display *dpy; + int screen; + SDL_NAME(XF86VidModeModeInfo)* modeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeDeleteModeLineReq *req; + xXF86OldVidModeDeleteModeLineReq *oldreq; + int majorVersion, minorVersion; + + XF86VidModeCheckExtension (dpy, info, 0); + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + + LockDisplay(dpy); + if (majorVersion < 2) { + GetOldReq(XF86VidModeDeleteModeLine, XF86OldVidModeDeleteModeLine, oldreq); + oldreq->reqType = info->codes->major_opcode; + oldreq->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; + oldreq->screen = screen; + oldreq->dotclock = modeline->dotclock; + oldreq->hdisplay = modeline->hdisplay; + oldreq->hsyncstart = modeline->hsyncstart; + oldreq->hsyncend = modeline->hsyncend; + oldreq->htotal = modeline->htotal; + oldreq->vdisplay = modeline->vdisplay; + oldreq->vsyncstart = modeline->vsyncstart; + oldreq->vsyncend = modeline->vsyncend; + oldreq->vtotal = modeline->vtotal; + oldreq->flags = modeline->flags; + oldreq->privsize = modeline->privsize; + if (modeline->privsize) { + oldreq->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } else { + GetReq(XF86VidModeDeleteModeLine, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine; + req->screen = screen; + req->dotclock = modeline->dotclock; + req->hdisplay = modeline->hdisplay; + req->hsyncstart = modeline->hsyncstart; + req->hsyncend = modeline->hsyncend; + req->htotal = modeline->htotal; + req->hskew = modeline->hskew; + req->vdisplay = modeline->vdisplay; + req->vsyncstart = modeline->vsyncstart; + req->vsyncend = modeline->vsyncend; + req->vtotal = modeline->vtotal; + req->flags = modeline->flags; + req->privsize = modeline->privsize; + if (modeline->privsize) { + req->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeModModeLine) (dpy, screen, modeline) + Display *dpy; + int screen; + SDL_NAME(XF86VidModeModeLine)* modeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeModModeLineReq *req; + xXF86OldVidModeModModeLineReq *oldreq; + int majorVersion, minorVersion; + + XF86VidModeCheckExtension (dpy, info, 0); + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + + LockDisplay(dpy); + if (majorVersion < 2) { + GetOldReq(XF86VidModeModModeLine, XF86OldVidModeModModeLine, oldreq); + oldreq->reqType = info->codes->major_opcode; + oldreq->xf86vidmodeReqType = X_XF86VidModeModModeLine; + oldreq->screen = screen; + oldreq->hdisplay = modeline->hdisplay; + oldreq->hsyncstart = modeline->hsyncstart; + oldreq->hsyncend = modeline->hsyncend; + oldreq->htotal = modeline->htotal; + oldreq->vdisplay = modeline->vdisplay; + oldreq->vsyncstart = modeline->vsyncstart; + oldreq->vsyncend = modeline->vsyncend; + oldreq->vtotal = modeline->vtotal; + oldreq->flags = modeline->flags; + oldreq->privsize = modeline->privsize; + if (modeline->privsize) { + oldreq->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } else { + GetReq(XF86VidModeModModeLine, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeModModeLine; + req->screen = screen; + req->hdisplay = modeline->hdisplay; + req->hsyncstart = modeline->hsyncstart; + req->hsyncend = modeline->hsyncend; + req->htotal = modeline->htotal; + req->hskew = modeline->hskew; + req->vdisplay = modeline->vdisplay; + req->vsyncstart = modeline->vsyncstart; + req->vsyncend = modeline->vsyncend; + req->vtotal = modeline->vtotal; + req->flags = modeline->flags; + req->privsize = modeline->privsize; + if (modeline->privsize) { + req->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +SDL_NAME(XF86VidModeValidateModeLine) (dpy, screen, modeline) + Display *dpy; + int screen; + SDL_NAME(XF86VidModeModeInfo)* modeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeValidateModeLineReq *req; + xXF86OldVidModeValidateModeLineReq *oldreq; + xXF86VidModeValidateModeLineReply rep; + int majorVersion, minorVersion; + + XF86VidModeCheckExtension (dpy, info, 0); + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + + LockDisplay(dpy); + + if (majorVersion < 2) { + GetOldReq(XF86VidModeValidateModeLine, XF86OldVidModeValidateModeLine, oldreq); + oldreq->reqType = info->codes->major_opcode; + oldreq->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; + oldreq->screen = screen; + oldreq->dotclock = modeline->dotclock; + oldreq->hdisplay = modeline->hdisplay; + oldreq->hsyncstart = modeline->hsyncstart; + oldreq->hsyncend = modeline->hsyncend; + oldreq->htotal = modeline->htotal; + oldreq->vdisplay = modeline->vdisplay; + oldreq->vsyncstart = modeline->vsyncstart; + oldreq->vsyncend = modeline->vsyncend; + oldreq->vtotal = modeline->vtotal; + oldreq->flags = modeline->flags; + oldreq->privsize = modeline->privsize; + if (modeline->privsize) { + oldreq->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } else { + GetReq(XF86VidModeValidateModeLine, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeValidateModeLine; + req->screen = screen; + req->dotclock = modeline->dotclock; + req->hdisplay = modeline->hdisplay; + req->hsyncstart = modeline->hsyncstart; + req->hsyncend = modeline->hsyncend; + req->htotal = modeline->htotal; + req->hskew = modeline->hskew; + req->vdisplay = modeline->vdisplay; + req->vsyncstart = modeline->vsyncstart; + req->vsyncend = modeline->vsyncend; + req->vtotal = modeline->vtotal; + req->flags = modeline->flags; + req->privsize = modeline->privsize; + if (modeline->privsize) { + req->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return MODE_BAD; + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.status; +} + +Bool +SDL_NAME(XF86VidModeSwitchMode)(dpy, screen, zoom) + Display* dpy; + int screen; + int zoom; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeSwitchModeReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeSwitchMode, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSwitchMode; + req->screen = screen; + req->zoom = zoom; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeSwitchToMode)(dpy, screen, modeline) + Display* dpy; + int screen; + SDL_NAME(XF86VidModeModeInfo)* modeline; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeSwitchToModeReq *req; + xXF86OldVidModeSwitchToModeReq *oldreq; + int majorVersion, minorVersion; + Bool protocolBug = False; + + XF86VidModeCheckExtension (dpy, info, False); + + /* + * Note: There was a bug in the protocol implementation in versions + * 0.x with x < 8 (the .private field wasn't expected to be sent over + * the wire). Check the server's version, and accept the old format + * if appropriate. + */ + + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + if (majorVersion == 0 && minorVersion < 8) { + protocolBug = True; +#ifdef DEBUG + fprintf(stderr, "XF86VidModeSwitchToMode: Warning: Xserver is" + "running an old version (%d.%d)\n", majorVersion, + minorVersion); +#endif + } + + LockDisplay(dpy); + if (majorVersion < 2) { + GetOldReq(XF86VidModeSwitchToMode, XF86OldVidModeSwitchToMode, oldreq); + oldreq->reqType = info->codes->major_opcode; + oldreq->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; + oldreq->screen = screen; + oldreq->dotclock = modeline->dotclock; + oldreq->hdisplay = modeline->hdisplay; + oldreq->hsyncstart = modeline->hsyncstart; + oldreq->hsyncend = modeline->hsyncend; + oldreq->htotal = modeline->htotal; + oldreq->vdisplay = modeline->vdisplay; + oldreq->vsyncstart = modeline->vsyncstart; + oldreq->vsyncend = modeline->vsyncend; + oldreq->vtotal = modeline->vtotal; + oldreq->flags = modeline->flags; + if (protocolBug) { + oldreq->privsize = 0; + } else { + oldreq->privsize = modeline->privsize; + if (modeline->privsize) { + oldreq->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } + } else { + GetReq(XF86VidModeSwitchToMode, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSwitchToMode; + req->screen = screen; + req->dotclock = modeline->dotclock; + req->hdisplay = modeline->hdisplay; + req->hsyncstart = modeline->hsyncstart; + req->hsyncend = modeline->hsyncend; + req->htotal = modeline->htotal; + req->hskew = modeline->hskew; + req->vdisplay = modeline->vdisplay; + req->vsyncstart = modeline->vsyncstart; + req->vsyncend = modeline->vsyncend; + req->vtotal = modeline->vtotal; + req->flags = modeline->flags; + if (protocolBug) { + req->privsize = 0; + } else { + req->privsize = modeline->privsize; + if (modeline->privsize) { + req->length += modeline->privsize; + Data32(dpy, (long *) modeline->private, + modeline->privsize * sizeof(INT32)); + } + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeLockModeSwitch)(dpy, screen, lock) + Display* dpy; + int screen; + int lock; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeLockModeSwitchReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeLockModeSwitch, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeLockModeSwitch; + req->screen = screen; + req->lock = lock; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetMonitor)(dpy, screen, monitor) + Display* dpy; + int screen; + SDL_NAME(XF86VidModeMonitor)* monitor; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetMonitorReply rep; + xXF86VidModeGetMonitorReq *req; + CARD32 syncrange; + int i; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeGetMonitor, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetMonitor; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + monitor->nhsync = rep.nhsync; + monitor->nvsync = rep.nvsync; +#if 0 + monitor->bandwidth = (float)rep.bandwidth / 1e6; +#endif + if (rep.vendorLength) { + if (!(monitor->vendor = (char *)Xcalloc(rep.vendorLength + 1, 1))) { + _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 + + ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + } else { + monitor->vendor = NULL; + } + if (rep.modelLength) { + if (!(monitor->model = Xcalloc(rep.modelLength + 1, 1))) { + _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 + + ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3)); + if (monitor->vendor) + Xfree(monitor->vendor); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + } else { + monitor->model = NULL; + } + if (!(monitor->hsync = Xcalloc(rep.nhsync, sizeof(SDL_NAME(XF86VidModeSyncRange))))) { + _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 + + ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3)); + + if (monitor->vendor) + Xfree(monitor->vendor); + if (monitor->model) + Xfree(monitor->model); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (!(monitor->vsync = Xcalloc(rep.nvsync, sizeof(SDL_NAME(XF86VidModeSyncRange))))) { + _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 + + ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3)); + if (monitor->vendor) + Xfree(monitor->vendor); + if (monitor->model) + Xfree(monitor->model); + Xfree(monitor->hsync); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + for (i = 0; i < rep.nhsync; i++) { + _XRead(dpy, (char *)&syncrange, 4); + monitor->hsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; + monitor->hsync[i].hi = (float)(syncrange >> 16) / 100.0; + } + for (i = 0; i < rep.nvsync; i++) { + _XRead(dpy, (char *)&syncrange, 4); + monitor->vsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0; + monitor->vsync[i].hi = (float)(syncrange >> 16) / 100.0; + } + if (rep.vendorLength) + _XReadPad(dpy, monitor->vendor, rep.vendorLength); + else + monitor->vendor = ""; + if (rep.modelLength) + _XReadPad(dpy, monitor->model, rep.modelLength); + else + monitor->model = ""; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetViewPort)(dpy, screen, x, y) + Display* dpy; + int screen; + int *x, *y; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetViewPortReply rep; + xXF86VidModeGetViewPortReq *req; + int majorVersion, minorVersion; + Bool protocolBug = False; + + XF86VidModeCheckExtension (dpy, info, False); + + /* + * Note: There was a bug in the protocol implementation in versions + * 0.x with x < 8 (no reply was sent, so the client would hang) + * Check the server's version, and don't wait for a reply with older + * versions. + */ + + SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion); + if (majorVersion == 0 && minorVersion < 8) { + protocolBug = True; +#ifdef DEBUG + fprintf(stderr, "XF86VidModeGetViewPort: Warning: Xserver is" + "running an old version (%d.%d)\n", majorVersion, + minorVersion); +#endif + } + LockDisplay(dpy); + GetReq(XF86VidModeGetViewPort, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetViewPort; + req->screen = screen; + if (protocolBug) { + *x = 0; + *y = 0; + } else { + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *x = rep.x; + *y = rep.y; + } + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeSetViewPort)(dpy, screen, x, y) + Display* dpy; + int screen; + int x, y; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeSetViewPortReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeSetViewPort, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSetViewPort; + req->screen = screen; + req->x = x; + req->y = y; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeGetDotClocks)(dpy, screen, + flagsPtr, numclocksPtr, maxclocksPtr, clocksPtr) + Display* dpy; + int screen; + int *flagsPtr, *numclocksPtr, *maxclocksPtr, *clocksPtr[]; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetDotClocksReply rep; + xXF86VidModeGetDotClocksReq *req; + int i, *dotclocks; + CARD32 dotclk; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeGetDotClocks, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetDotClocks; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, + (SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2, xFalse)) + { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *numclocksPtr = rep.clocks; + *maxclocksPtr = rep.maxclocks; + *flagsPtr = rep.flags; + + if (!(dotclocks = (int*) Xcalloc(rep.clocks, sizeof(int)))) { + _XEatData(dpy, (rep.clocks) * 4); + Xfree(dotclocks); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + for (i = 0; i < rep.clocks; i++) { + _XRead(dpy, (char*)&dotclk, 4); + dotclocks[i] = dotclk; + } + *clocksPtr = dotclocks; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +SDL_NAME(XF86VidModeSetGammaRamp) ( + Display *dpy, + int screen, + int size, + unsigned short *red, + unsigned short *green, + unsigned short *blue +) +{ + int length = (size + 1) & ~1; + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeSetGammaRampReq *req; + + XF86VidModeCheckExtension (dpy, info, False); + LockDisplay(dpy); + GetReq(XF86VidModeSetGammaRamp, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeSetGammaRamp; + req->screen = screen; + req->length += (length >> 1) * 3; + req->size = size; + _XSend(dpy, (char*)red, size * 2); + _XSend(dpy, (char*)green, size * 2); + _XSend(dpy, (char*)blue, size * 2); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool +SDL_NAME(XF86VidModeGetGammaRamp) ( + Display *dpy, + int screen, + int size, + unsigned short *red, + unsigned short *green, + unsigned short *blue +) +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetGammaRampReq *req; + xXF86VidModeGetGammaRampReply rep; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeGetGammaRamp, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetGammaRamp; + req->screen = screen; + req->size = size; + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if(rep.size) { + _XRead(dpy, (char*)red, rep.size << 1); + _XRead(dpy, (char*)green, rep.size << 1); + _XRead(dpy, (char*)blue, rep.size << 1); + } + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool SDL_NAME(XF86VidModeGetGammaRampSize)( + Display *dpy, + int screen, + int *size +) +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86VidModeGetGammaRampSizeReq *req; + xXF86VidModeGetGammaRampSizeReply rep; + + *size = 0; + + XF86VidModeCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86VidModeGetGammaRampSize, req); + req->reqType = info->codes->major_opcode; + req->xf86vidmodeReqType = X_XF86VidModeGetGammaRampSize; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + *size = rep.size; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/Xext.h b/apps/plugins/sdl/src/video/Xext/extensions/Xext.h new file mode 100644 index 0000000000..9edf3194b4 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/Xext.h @@ -0,0 +1,50 @@ +/* +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ +/* $XFree86: xc/include/extensions/Xext.h,v 1.7 2005/01/27 03:03:09 dawes Exp $ */ + +#ifndef _XEXT_H_ +#define _XEXT_H_ + +#include + +_XFUNCPROTOBEGIN + +typedef int (*XExtensionErrorHandler)(Display *, _Xconst char *, + _Xconst char *); + +extern XExtensionErrorHandler XSetExtensionErrorHandler( + XExtensionErrorHandler handler +); + +extern int XMissingExtension( + Display* /* dpy */, + _Xconst char* /* ext_name */ +); + +_XFUNCPROTOEND + +#define X_EXTENSION_UNKNOWN "unknown" +#define X_EXTENSION_MISSING "missing" + +#endif /* _XEXT_H_ */ diff --git a/apps/plugins/sdl/src/video/Xext/extensions/Xinerama.h b/apps/plugins/sdl/src/video/Xext/extensions/Xinerama.h new file mode 100644 index 0000000000..54f2fe17d2 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/Xinerama.h @@ -0,0 +1,46 @@ +/* $XFree86: xc/include/extensions/Xinerama.h,v 3.2 2000/03/01 01:04:20 dawes Exp $ */ + +#ifndef _Xinerama_h +#define _Xinerama_h + +#include "SDL_name.h" + +typedef struct { + int screen_number; + short x_org; + short y_org; + short width; + short height; +} SDL_NAME(XineramaScreenInfo); + +Bool SDL_NAME(XineramaQueryExtension) ( + Display *dpy, + int *event_base, + int *error_base +); + +Status SDL_NAME(XineramaQueryVersion)( + Display *dpy, + int *major, + int *minor +); + +Bool SDL_NAME(XineramaIsActive)(Display *dpy); + + +/* + Returns the number of heads and a pointer to an array of + structures describing the position and size of the individual + heads. Returns NULL and number = 0 if Xinerama is not active. + + Returned array should be freed with XFree(). +*/ + +SDL_NAME(XineramaScreenInfo) * +SDL_NAME(XineramaQueryScreens)( + Display *dpy, + int *number +); + +#endif /* _Xinerama_h */ + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/Xv.h b/apps/plugins/sdl/src/video/Xext/extensions/Xv.h new file mode 100644 index 0000000000..a6a027195f --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/Xv.h @@ -0,0 +1,129 @@ +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/include/extensions/Xv.h,v 1.5 1999/12/11 19:28:48 mvojkovi Exp $ */ + +#ifndef XV_H +#define XV_H +/* +** File: +** +** Xv.h --- Xv shared library and server header file +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 05.15.91 Carver +** - version 2.0 upgrade +** +** 01.24.91 Carver +** - version 1.4 upgrade +** +*/ + +#include + +#define XvName "XVideo" +#define XvVersion 2 +#define XvRevision 2 + +/* Symbols */ + +typedef XID XvPortID; +typedef XID XvEncodingID; + +#define XvNone 0 + +#define XvInput 0 +#define XvOutput 1 + +#define XvInputMask (1L< +#include "Xv.h" +#include "SDL_name.h" + +typedef struct { + int numerator; + int denominator; +} SDL_NAME(XvRational); + +typedef struct { + int flags; /* XvGettable, XvSettable */ + int min_value; + int max_value; + char *name; +} SDL_NAME(XvAttribute); + +typedef struct { + XvEncodingID encoding_id; + char *name; + unsigned long width; + unsigned long height; + SDL_NAME(XvRational) rate; + unsigned long num_encodings; +} SDL_NAME(XvEncodingInfo); + +typedef struct { + char depth; + unsigned long visual_id; +} SDL_NAME(XvFormat); + +typedef struct { + XvPortID base_id; + unsigned long num_ports; + char type; + char *name; + unsigned long num_formats; + SDL_NAME(XvFormat) *formats; + unsigned long num_adaptors; +} SDL_NAME(XvAdaptorInfo); + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; /* drawable */ + unsigned long reason; /* what generated this event */ + XvPortID port_id; /* what port */ + Time time; /* milliseconds */ +} SDL_NAME(XvVideoNotifyEvent); + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + XvPortID port_id; /* what port */ + Time time; /* milliseconds */ + Atom attribute; /* atom that identifies attribute */ + long value; /* value of attribute */ +} SDL_NAME(XvPortNotifyEvent); + +typedef union { + int type; + SDL_NAME(XvVideoNotifyEvent) xvvideo; + SDL_NAME(XvPortNotifyEvent) xvport; + long pad[24]; +} SDL_NAME(XvEvent); + +typedef struct { + int id; /* Unique descriptor for the format */ + int type; /* XvRGB, XvYUV */ + int byte_order; /* LSBFirst, MSBFirst */ + char guid[16]; /* Globally Unique IDentifier */ + int bits_per_pixel; + int format; /* XvPacked, XvPlanar */ + int num_planes; + + /* for RGB formats only */ + int depth; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + + /* for YUV formats only */ + unsigned int y_sample_bits; + unsigned int u_sample_bits; + unsigned int v_sample_bits; + unsigned int horz_y_period; + unsigned int horz_u_period; + unsigned int horz_v_period; + unsigned int vert_y_period; + unsigned int vert_u_period; + unsigned int vert_v_period; + char component_order[32]; /* eg. UYVY */ + int scanline_order; /* XvTopToBottom, XvBottomToTop */ +} SDL_NAME(XvImageFormatValues); + +typedef struct { + int id; + int width, height; + int data_size; /* bytes */ + int num_planes; + int *pitches; /* bytes */ + int *offsets; /* bytes */ + char *data; + XPointer obdata; +} SDL_NAME(XvImage); + +_XFUNCPROTOBEGIN + +extern int SDL_NAME(XvQueryExtension)( +#if NeedFunctionPrototypes + Display* /* display */, + unsigned int* /* p_version */, + unsigned int* /* p_revision */, + unsigned int* /* p_requestBase */, + unsigned int* /* p_eventBase */, + unsigned int* /* p_errorBase */ +#endif +); + +extern int SDL_NAME(XvQueryAdaptors)( +#if NeedFunctionPrototypes + Display* /* display */, + Window /* window */, + unsigned int* /* p_nAdaptors */, + SDL_NAME(XvAdaptorInfo)** /* p_pAdaptors */ +#endif +); + +extern int SDL_NAME(XvQueryEncodings)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + unsigned int* /* p_nEncoding */, + SDL_NAME(XvEncodingInfo)** /* p_pEncoding */ +#endif +); + +extern int SDL_NAME(XvPutVideo)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Drawable /* d */, + GC /* gc */, + int /* vx */, + int /* vy */, + unsigned int /* vw */, + unsigned int /* vh */, + int /* dx */, + int /* dy */, + unsigned int /* dw */, + unsigned int /* dh */ +#endif +); + +extern int SDL_NAME(XvPutStill)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Drawable /* d */, + GC /* gc */, + int /* vx */, + int /* vy */, + unsigned int /* vw */, + unsigned int /* vh */, + int /* dx */, + int /* dy */, + unsigned int /* dw */, + unsigned int /* dh */ +#endif +); + +extern int SDL_NAME(XvGetVideo)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Drawable /* d */, + GC /* gc */, + int /* vx */, + int /* vy */, + unsigned int /* vw */, + unsigned int /* vh */, + int /* dx */, + int /* dy */, + unsigned int /* dw */, + unsigned int /* dh */ +#endif +); + +extern int SDL_NAME(XvGetStill)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Drawable /* d */, + GC /* gc */, + int /* vx */, + int /* vy */, + unsigned int /* vw */, + unsigned int /* vh */, + int /* dx */, + int /* dy */, + unsigned int /* dw */, + unsigned int /* dh */ +#endif +); + +extern int SDL_NAME(XvStopVideo)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Drawable /* drawable */ +#endif +); + +extern int SDL_NAME(XvGrabPort)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Time /* time */ +#endif +); + +extern int SDL_NAME(XvUngrabPort)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Time /* time */ +#endif +); + +extern int SDL_NAME(XvSelectVideoNotify)( +#if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + Bool /* onoff */ +#endif +); + +extern int SDL_NAME(XvSelectPortNotify)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Bool /* onoff */ +#endif +); + +extern int SDL_NAME(XvSetPortAttribute)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Atom /* attribute */, + int /* value */ +#endif +); + +extern int SDL_NAME(XvGetPortAttribute)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Atom /* attribute */, + int* /* p_value */ +#endif +); + +extern int SDL_NAME(XvQueryBestSize)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + Bool /* motion */, + unsigned int /* vid_w */, + unsigned int /* vid_h */, + unsigned int /* drw_w */, + unsigned int /* drw_h */, + unsigned int* /* p_actual_width */, + unsigned int* /* p_actual_width */ +#endif +); + +extern SDL_NAME(XvAttribute)* SDL_NAME(XvQueryPortAttributes)( +#if NeedFunctionPrototypes + Display* /* display */, + XvPortID /* port */, + int* /* number */ +#endif +); + + +extern void SDL_NAME(XvFreeAdaptorInfo)( +#if NeedFunctionPrototypes + SDL_NAME(XvAdaptorInfo)* /* adaptors */ +#endif +); + +extern void SDL_NAME(XvFreeEncodingInfo)( +#if NeedFunctionPrototypes + SDL_NAME(XvEncodingInfo)* /* encodings */ +#endif +); + + +extern SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) ( +#if NeedFunctionPrototypes + Display *display, + XvPortID port_id, + int *count_return +#endif +); + +extern SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) ( +#if NeedFunctionPrototypes + Display *display, + XvPortID port, + int id, + char *data, + int width, + int height +#endif +); + +extern int SDL_NAME(XvPutImage) ( +#if NeedFunctionPrototypes + Display *display, + XvPortID id, + Drawable d, + GC gc, + SDL_NAME(XvImage) *image, + int src_x, + int src_y, + unsigned int src_w, + unsigned int src_h, + int dest_x, + int dest_y, + unsigned int dest_w, + unsigned int dest_h +#endif +); + +extern int SDL_NAME(XvShmPutImage) ( +#if NeedFunctionPrototypes + Display *display, + XvPortID id, + Drawable d, + GC gc, + SDL_NAME(XvImage) *image, + int src_x, + int src_y, + unsigned int src_w, + unsigned int src_h, + int dest_x, + int dest_y, + unsigned int dest_w, + unsigned int dest_h, + Bool send_event +#endif +); + +#ifdef _XSHM_H_ + +extern SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) ( +#if NeedFunctionPrototypes + Display *display, + XvPortID port, + int id, + char* data, + int width, + int height, + XShmSegmentInfo *shminfo +#endif +); + +#endif + + +_XFUNCPROTOEND + +#endif /* XVLIB_H */ diff --git a/apps/plugins/sdl/src/video/Xext/extensions/Xvproto.h b/apps/plugins/sdl/src/video/Xext/extensions/Xvproto.h new file mode 100644 index 0000000000..b4d8f22cdc --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/Xvproto.h @@ -0,0 +1,604 @@ +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/include/extensions/Xvproto.h,v 1.6 2001/05/07 21:37:12 tsi Exp $ */ + +#ifndef XVPROTO_H +#define XVPROTO_H +/* +** File: +** +** Xvproto.h --- Xv protocol header file +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include + +/* Symbols: These are undefined at the end of this file to restore the + values they have in Xv.h */ + +#define XvPortID CARD32 +#define XvEncodingID CARD32 +#define ShmSeg CARD32 +#define VisualID CARD32 +#define Drawable CARD32 +#define GContext CARD32 +#define Time CARD32 +#define Atom CARD32 + +/* Structures */ + +typedef struct { + INT32 numerator B32; + INT32 denominator B32; +} xvRational; +#define sz_xvRational 8 + +typedef struct { + XvPortID base_id B32; + CARD16 name_size B16; + CARD16 num_ports B16; + CARD16 num_formats B16; + CARD8 type; + CARD8 pad; +} xvAdaptorInfo; +#define sz_xvAdaptorInfo 12 + +typedef struct { + XvEncodingID encoding B32; + CARD16 name_size B16; + CARD16 width B16, height B16; + xvRational rate; + CARD16 pad B16; +} xvEncodingInfo; +#define sz_xvEncodingInfo (12 + sz_xvRational) + +typedef struct { + VisualID visual B32; + CARD8 depth; + CARD8 pad1; + CARD16 pad2 B16; +} xvFormat; +#define sz_xvFormat 8 + +typedef struct { + CARD32 flags B32; + INT32 min B32; + INT32 max B32; + CARD32 size B32; +} xvAttributeInfo; +#define sz_xvAttributeInfo 16 + +typedef struct { + CARD32 id B32; + CARD8 type; + CARD8 byte_order; + CARD16 pad1 B16; + CARD8 guid[16]; + CARD8 bpp; + CARD8 num_planes; + CARD16 pad2 B16; + CARD8 depth; + CARD8 pad3; + CARD16 pad4 B16; + CARD32 red_mask B32; + CARD32 green_mask B32; + CARD32 blue_mask B32; + CARD8 format; + CARD8 pad5; + CARD16 pad6 B16; + CARD32 y_sample_bits B32; + CARD32 u_sample_bits B32; + CARD32 v_sample_bits B32; + CARD32 horz_y_period B32; + CARD32 horz_u_period B32; + CARD32 horz_v_period B32; + CARD32 vert_y_period B32; + CARD32 vert_u_period B32; + CARD32 vert_v_period B32; + CARD8 comp_order[32]; + CARD8 scanline_order; + CARD8 pad7; + CARD16 pad8 B16; + CARD32 pad9 B32; + CARD32 pad10 B32; +} xvImageFormatInfo; +#define sz_xvImageFormatInfo 128 + + +/* Requests */ + +#define xv_QueryExtension 0 +#define xv_QueryAdaptors 1 +#define xv_QueryEncodings 2 +#define xv_GrabPort 3 +#define xv_UngrabPort 4 +#define xv_PutVideo 5 +#define xv_PutStill 6 +#define xv_GetVideo 7 +#define xv_GetStill 8 +#define xv_StopVideo 9 +#define xv_SelectVideoNotify 10 +#define xv_SelectPortNotify 11 +#define xv_QueryBestSize 12 +#define xv_SetPortAttribute 13 +#define xv_GetPortAttribute 14 +#define xv_QueryPortAttributes 15 +#define xv_ListImageFormats 16 +#define xv_QueryImageAttributes 17 +#define xv_PutImage 18 +#define xv_ShmPutImage 19 +#define xv_LastRequest xv_ShmPutImage + +#define xvNumRequests (xv_LastRequest + 1) + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; +} xvQueryExtensionReq; +#define sz_xvQueryExtensionReq 4 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + CARD32 window B32; +} xvQueryAdaptorsReq; +#define sz_xvQueryAdaptorsReq 8 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + CARD32 port B32; +} xvQueryEncodingsReq; +#define sz_xvQueryEncodingsReq 8 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + INT16 vid_x B16; + INT16 vid_y B16; + CARD16 vid_w B16; + CARD16 vid_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; +} xvPutVideoReq; +#define sz_xvPutVideoReq 32 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + INT16 vid_x B16; + INT16 vid_y B16; + CARD16 vid_w B16; + CARD16 vid_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; +} xvPutStillReq; +#define sz_xvPutStillReq 32 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + INT16 vid_x B16; + INT16 vid_y B16; + CARD16 vid_w B16; + CARD16 vid_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; +} xvGetVideoReq; +#define sz_xvGetVideoReq 32 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + INT16 vid_x B16; + INT16 vid_y B16; + CARD16 vid_w B16; + CARD16 vid_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; +} xvGetStillReq; +#define sz_xvGetStillReq 32 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Time time B32; +} xvGrabPortReq; +#define sz_xvGrabPortReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Time time B32; +} xvUngrabPortReq; +#define sz_xvUngrabPortReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + Drawable drawable B32; + BOOL onoff; + CARD8 pad1; + CARD16 pad2; +} xvSelectVideoNotifyReq; +#define sz_xvSelectVideoNotifyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + BOOL onoff; + CARD8 pad1; + CARD16 pad2; +} xvSelectPortNotifyReq; +#define sz_xvSelectPortNotifyReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; +} xvStopVideoReq; +#define sz_xvStopVideoReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Atom attribute B32; + INT32 value B32; +} xvSetPortAttributeReq; +#define sz_xvSetPortAttributeReq 16 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Atom attribute B32; +} xvGetPortAttributeReq; +#define sz_xvGetPortAttributeReq 12 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + CARD16 vid_w B16; + CARD16 vid_h B16; + CARD16 drw_w B16; + CARD16 drw_h B16; + CARD8 motion; + CARD8 pad1; + CARD16 pad2 B16; +} xvQueryBestSizeReq; +#define sz_xvQueryBestSizeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; +} xvQueryPortAttributesReq; +#define sz_xvQueryPortAttributesReq 8 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + CARD32 id B32; + INT16 src_x B16; + INT16 src_y B16; + CARD16 src_w B16; + CARD16 src_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; + CARD16 width B16; + CARD16 height B16; +} xvPutImageReq; +#define sz_xvPutImageReq 40 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; + Drawable drawable B32; + GContext gc B32; + ShmSeg shmseg B32; + CARD32 id B32; + CARD32 offset B32; + INT16 src_x B16; + INT16 src_y B16; + CARD16 src_w B16; + CARD16 src_h B16; + INT16 drw_x B16; + INT16 drw_y B16; + CARD16 drw_w B16; + CARD16 drw_h B16; + CARD16 width B16; + CARD16 height B16; + CARD8 send_event; + CARD8 pad1; + CARD16 pad2 B16; +} xvShmPutImageReq; +#define sz_xvShmPutImageReq 52 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + XvPortID port B32; +} xvListImageFormatsReq; +#define sz_xvListImageFormatsReq 8 + +typedef struct { + CARD8 reqType; + CARD8 xvReqType; + CARD16 length B16; + CARD32 port B32; + CARD32 id B32; + CARD16 width B16; + CARD16 height B16; +} xvQueryImageAttributesReq; +#define sz_xvQueryImageAttributesReq 16 + + +/* Replies */ + +typedef struct _QueryExtensionReply { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 version B16; + CARD16 revision B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryExtensionReply; +#define sz_xvQueryExtensionReply 32 + +typedef struct _QueryAdaptorsReply { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 num_adaptors B16; + CARD16 pads3 B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryAdaptorsReply; +#define sz_xvQueryAdaptorsReply 32 + +typedef struct _QueryEncodingsReply { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 num_encodings B16; + CARD32 padl3 B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryEncodingsReply; +#define sz_xvQueryEncodingsReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE result; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 padl3 B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvGrabPortReply; +#define sz_xvGrabPortReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + INT32 value B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvGetPortAttributeReply; +#define sz_xvGetPortAttributeReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 actual_width B16; + CARD16 actual_height B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryBestSizeReply; +#define sz_xvQueryBestSizeReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 num_attributes B32; + CARD32 text_size B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryPortAttributesReply; +#define sz_xvQueryPortAttributesReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 num_formats B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvListImageFormatsReply; +#define sz_xvListImageFormatsReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 num_planes B32; + CARD32 data_size B32; + CARD16 width B16; + CARD16 height B16; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xvQueryImageAttributesReply; +#define sz_xvQueryImageAttributesReply 32 + +/* DEFINE EVENT STRUCTURE */ + +typedef struct { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + BYTE type; + BYTE reason; + CARD16 sequenceNumber B16; + Time time B32; + Drawable drawable B32; + XvPortID port B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; + } videoNotify; + struct { + BYTE type; + BYTE padb1; + CARD16 sequenceNumber B16; + Time time B32; + XvPortID port B32; + Atom attribute B32; + INT32 value B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; + } portNotify; + } u; +} xvEvent; + +#undef XvPortID +#undef XvEncodingID +#undef ShmSeg +#undef VisualID +#undef Drawable +#undef GContext +#undef Time +#undef Atom + +#endif /* XVPROTO_H */ + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/extutil.h b/apps/plugins/sdl/src/video/Xext/extensions/extutil.h new file mode 100644 index 0000000000..f3a741ea22 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/extutil.h @@ -0,0 +1,226 @@ +/* + * $Xorg: extutil.h,v 1.4 2001/02/09 02:03:24 xorgcvs Exp $ + * +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Jim Fulton, MIT The Open Group + * + * Xlib Extension-Writing Utilities + * + * This package contains utilities for writing the client API for various + * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND + * ARE SUBJECT TO CHANGE! + */ +/* $XFree86: xc/include/extensions/extutil.h,v 1.9 2001/12/14 19:53:28 dawes Exp $ */ + +#ifndef _EXTUTIL_H_ +#define _EXTUTIL_H_ + +#include "SDL_stdinc.h" /* For portable string functions */ + +#include "./Xext.h" + +/* + * We need to keep a list of open displays since the Xlib display list isn't + * public. We also have to per-display info in a separate block since it isn't + * stored directly in the Display structure. + */ +typedef struct _XExtDisplayInfo { + struct _XExtDisplayInfo *next; /* keep a linked list */ + Display *display; /* which display this is */ + XExtCodes *codes; /* the extension protocol codes */ + XPointer data; /* extra data for extension to use */ +} XExtDisplayInfo; + +typedef struct _XExtensionInfo { + XExtDisplayInfo *head; /* start of list */ + XExtDisplayInfo *cur; /* most recently used */ + int ndisplays; /* number of displays */ +} XExtensionInfo; + +typedef struct _XExtensionHooks { + int (*create_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*copy_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*flush_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*free_gc)( +#if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ +#endif +); + int (*create_font)( +#if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + int (*free_font)( +#if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ +#endif +); + int (*close_display)( +#if NeedNestedPrototypes + Display* /* display */, + XExtCodes* /* codes */ +#endif +); + Bool (*wire_to_event)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + Status (*event_to_wire)( +#if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ +#endif +); + int (*error)( +#if NeedNestedPrototypes + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ +#endif +); + char *(*error_string)( +#if NeedNestedPrototypes + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ +#endif +); +} XExtensionHooks; + +extern XExtensionInfo *XextCreateExtension( +#if NeedFunctionPrototypes + void +#endif +); +extern void XextDestroyExtension( +#if NeedFunctionPrototypes + XExtensionInfo* /* info */ +#endif +); +extern XExtDisplayInfo *XextAddDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */, + char* /* ext_name */, + XExtensionHooks* /* hooks */, + int /* nevents */, + XPointer /* data */ +#endif +); +extern int XextRemoveDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */ +#endif +); +extern XExtDisplayInfo *XextFindDisplay( +#if NeedFunctionPrototypes + XExtensionInfo* /* extinfo */, + Display* /* dpy */ +#endif +); + +#define XextHasExtension(i) ((i) && ((i)->codes)) +#define XextCheckExtension(dpy,i,name,val) \ + if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; } +#define XextSimpleCheckExtension(dpy,i,name) \ + if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; } + + +/* + * helper macros to generate code that is common to all extensions; caller + * should prefix it with static if extension source is in one file; this + * could be a utility function, but have to stack 6 unused arguments for + * something that is called many, many times would be bad. + */ +#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \ +XExtDisplayInfo *proc (Display *dpy) \ +{ \ + XExtDisplayInfo *dpyinfo; \ + if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \ + if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \ + dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \ + return dpyinfo; \ +} + +#define XEXT_FIND_DISPLAY_PROTO(proc) \ + XExtDisplayInfo *proc(Display *dpy) + +#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \ +int proc (Display *dpy, XExtCodes *codes) \ +{ \ + return XextRemoveDisplay (extinfo, dpy); \ +} + +#define XEXT_CLOSE_DISPLAY_PROTO(proc) \ + int proc(Display *dpy, XExtCodes *codes) + +#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \ +char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \ +{ \ + code -= codes->first_error; \ + if (code >= 0 && code < nerr) { \ + char tmp[256]; \ + SDL_snprintf (tmp, SDL_arraysize(tmp), "%s.%d", extname, code); \ + XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \ + return buf; \ + } \ + return (char *)0; \ +} + +#define XEXT_ERROR_STRING_PROTO(proc) \ + char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n) +#endif diff --git a/apps/plugins/sdl/src/video/Xext/extensions/panoramiXext.h b/apps/plugins/sdl/src/video/Xext/extensions/panoramiXext.h new file mode 100644 index 0000000000..e89d8917bb --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/panoramiXext.h @@ -0,0 +1,52 @@ +/* $Xorg: panoramiXext.h,v 1.4 2000/08/18 04:05:45 coskrey Exp $ */ +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ +/* + * PanoramiX definitions + */ +/* $XFree86: xc/include/extensions/panoramiXext.h,v 3.6 2001/01/17 17:53:22 dawes Exp $ */ + +#include "SDL_name.h" + +/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */ + +#define PANORAMIX_MAJOR_VERSION 1 /* current version number */ +#define PANORAMIX_MINOR_VERSION 1 + +typedef struct { + Window window; /* PanoramiX window - may not exist */ + int screen; + int State; /* PanroamiXOff, PanoramiXOn */ + int width; /* width of this screen */ + int height; /* height of this screen */ + int ScreenCount; /* real physical number of screens */ + XID eventMask; /* selected events for this client */ +} SDL_NAME(XPanoramiXInfo); + +extern SDL_NAME(XPanoramiXInfo) *SDL_NAME(XPanoramiXAllocInfo) ( +#if NeedFunctionPrototypes + void +#endif +); diff --git a/apps/plugins/sdl/src/video/Xext/extensions/panoramiXproto.h b/apps/plugins/sdl/src/video/Xext/extensions/panoramiXproto.h new file mode 100644 index 0000000000..fe3826eb3b --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/panoramiXproto.h @@ -0,0 +1,192 @@ +/* $Xorg: panoramiXproto.h,v 1.4 2000/08/18 04:05:45 coskrey Exp $ */ +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ +/* $XFree86: xc/include/extensions/panoramiXproto.h,v 3.6 2001/01/17 17:53:22 dawes Exp $ */ + +/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */ + +#ifndef _PANORAMIXPROTO_H_ +#define _PANORAMIXPROTO_H_ + +#define PANORAMIX_PROTOCOL_NAME "XINERAMA" + +#define X_PanoramiXQueryVersion 0 +#define X_PanoramiXGetState 1 +#define X_PanoramiXGetScreenCount 2 +#define X_PanoramiXGetScreenSize 3 + +#define X_XineramaIsActive 4 +#define X_XineramaQueryScreens 5 + +typedef struct _PanoramiXQueryVersion { + CARD8 reqType; /* always PanoramiXReqCode */ + CARD8 panoramiXReqType; /* always X_PanoramiXQueryVersion */ + CARD16 length B16; + CARD8 clientMajor; + CARD8 clientMinor; + CARD16 unused B16; +} xPanoramiXQueryVersionReq; + +#define sz_xPanoramiXQueryVersionReq 8 + +typedef struct { + CARD8 type; /* must be X_Reply */ + CARD8 pad1; /* unused */ + CARD16 sequenceNumber B16; /* last sequence number */ + CARD32 length B32; /* 0 */ + CARD16 majorVersion B16; + CARD16 minorVersion B16; + CARD32 pad2 B32; /* unused */ + CARD32 pad3 B32; /* unused */ + CARD32 pad4 B32; /* unused */ + CARD32 pad5 B32; /* unused */ + CARD32 pad6 B32; /* unused */ +} xPanoramiXQueryVersionReply; + +#define sz_xPanoramiXQueryVersionReply 32 + + +typedef struct _PanoramiXGetState { + CARD8 reqType; /* always PanoramiXReqCode */ + CARD8 panoramiXReqType; /* always X_PanoramiXGetState */ + CARD16 length B16; + CARD32 window B32; +} xPanoramiXGetStateReq; +#define sz_xPanoramiXGetStateReq 8 + +typedef struct { + BYTE type; + BYTE state; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 window B32; + CARD32 pad1 B32; /* unused */ + CARD32 pad2 B32; /* unused */ + CARD32 pad3 B32; /* unused */ + CARD32 pad4 B32; /* unused */ + CARD32 pad5 B32; /* unused */ +} xPanoramiXGetStateReply; + +#define sz_panoramiXGetStateReply 32 + +typedef struct _PanoramiXGetScreenCount { + CARD8 reqType; /* always PanoramiXReqCode */ + CARD8 panoramiXReqType; /* always X_PanoramiXGetScreenCount */ + CARD16 length B16; + CARD32 window B32; +} xPanoramiXGetScreenCountReq; +#define sz_xPanoramiXGetScreenCountReq 8 + +typedef struct { + BYTE type; + BYTE ScreenCount; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 window B32; + CARD32 pad1 B32; /* unused */ + CARD32 pad2 B32; /* unused */ + CARD32 pad3 B32; /* unused */ + CARD32 pad4 B32; /* unused */ + CARD32 pad5 B32; /* unused */ +} xPanoramiXGetScreenCountReply; +#define sz_panoramiXGetScreenCountReply 32 + +typedef struct _PanoramiXGetScreenSize { + CARD8 reqType; /* always PanoramiXReqCode */ + CARD8 panoramiXReqType; /* always X_PanoramiXGetState */ + CARD16 length B16; + CARD32 window B32; + CARD32 screen B32; +} xPanoramiXGetScreenSizeReq; +#define sz_xPanoramiXGetScreenSizeReq 12 + +typedef struct { + BYTE type; + CARD8 pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 width B32; + CARD32 height B32; + CARD32 window B32; + CARD32 screen B32; + CARD32 pad2 B32; /* unused */ + CARD32 pad3 B32; /* unused */ +} xPanoramiXGetScreenSizeReply; +#define sz_panoramiXGetScreenSizeReply 32 + +/************ Alternate protocol ******************/ + +typedef struct { + CARD8 reqType; + CARD8 panoramiXReqType; + CARD16 length B16; +} xXineramaIsActiveReq; +#define sz_xXineramaIsActiveReq 4 + +typedef struct { + BYTE type; + CARD8 pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 state B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXineramaIsActiveReply; +#define sz_XineramaIsActiveReply 32 + + +typedef struct { + CARD8 reqType; + CARD8 panoramiXReqType; + CARD16 length B16; +} xXineramaQueryScreensReq; +#define sz_xXineramaQueryScreensReq 4 + +typedef struct { + BYTE type; + CARD8 pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 number B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXineramaQueryScreensReply; +#define sz_XineramaQueryScreensReply 32 + +typedef struct { + INT16 x_org B16; + INT16 y_org B16; + CARD16 width B16; + CARD16 height B16; +} xXineramaScreenInfo; +#define sz_XineramaScreenInfo 8 + +#endif diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86dga.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga.h new file mode 100644 index 0000000000..c71ef4b14a --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga.h @@ -0,0 +1,265 @@ +/* + Copyright (c) 1999 XFree86 Inc +*/ +/* $XFree86: xc/include/extensions/xf86dga.h,v 3.21 2001/08/01 00:44:36 tsi Exp $ */ + +#ifndef _XF86DGA_H_ +#define _XF86DGA_H_ + +#include +#include "xf86dga1.h" +#include "SDL_name.h" + +#define X_XDGAQueryVersion 0 + +/* 1 through 9 are in xf86dga1.h */ + +/* 10 and 11 are reserved to avoid conflicts with rogue DGA extensions */ + +#define X_XDGAQueryModes 12 +#define X_XDGASetMode 13 +#define X_XDGASetViewport 14 +#define X_XDGAInstallColormap 15 +#define X_XDGASelectInput 16 +#define X_XDGAFillRectangle 17 +#define X_XDGACopyArea 18 +#define X_XDGACopyTransparentArea 19 +#define X_XDGAGetViewportStatus 20 +#define X_XDGASync 21 +#define X_XDGAOpenFramebuffer 22 +#define X_XDGACloseFramebuffer 23 +#define X_XDGASetClientVersion 24 +#define X_XDGAChangePixmapMode 25 +#define X_XDGACreateColormap 26 + + +#define XDGAConcurrentAccess 0x00000001 +#define XDGASolidFillRect 0x00000002 +#define XDGABlitRect 0x00000004 +#define XDGABlitTransRect 0x00000008 +#define XDGAPixmap 0x00000010 + +#define XDGAInterlaced 0x00010000 +#define XDGADoublescan 0x00020000 + +#define XDGAFlipImmediate 0x00000001 +#define XDGAFlipRetrace 0x00000002 + +#define XDGANeedRoot 0x00000001 + +#define XF86DGANumberEvents 7 + +#define XDGAPixmapModeLarge 0 +#define XDGAPixmapModeSmall 1 + +#define XF86DGAClientNotLocal 0 +#define XF86DGANoDirectVideoMode 1 +#define XF86DGAScreenNotActive 2 +#define XF86DGADirectNotActivated 3 +#define XF86DGAOperationNotSupported 4 +#define XF86DGANumberErrors (XF86DGAOperationNotSupported + 1) + + +typedef struct { + int num; /* A unique identifier for the mode (num > 0) */ + char *name; /* name of mode given in the XF86Config */ + float verticalRefresh; + int flags; /* DGA_CONCURRENT_ACCESS, etc... */ + int imageWidth; /* linear accessible portion (pixels) */ + int imageHeight; + int pixmapWidth; /* Xlib accessible portion (pixels) */ + int pixmapHeight; /* both fields ignored if no concurrent access */ + int bytesPerScanline; + int byteOrder; /* MSBFirst, LSBFirst */ + int depth; + int bitsPerPixel; + unsigned long redMask; + unsigned long greenMask; + unsigned long blueMask; + short visualClass; + int viewportWidth; + int viewportHeight; + int xViewportStep; /* viewport position granularity */ + int yViewportStep; + int maxViewportX; /* max viewport origin */ + int maxViewportY; + int viewportFlags; /* types of page flipping possible */ + int reserved1; + int reserved2; +} SDL_NAME(XDGAMode); + + +typedef struct { + SDL_NAME(XDGAMode) mode; + unsigned char *data; + Pixmap pixmap; +} SDL_NAME(XDGADevice); + + +#ifndef _XF86DGA_SERVER_ +_XFUNCPROTOBEGIN + +typedef struct { + int type; + unsigned long serial; + Display *display; + int screen; + Time time; + unsigned int state; + unsigned int button; +} SDL_NAME(XDGAButtonEvent); + +typedef struct { + int type; + unsigned long serial; + Display *display; + int screen; + Time time; + unsigned int state; + unsigned int keycode; +} SDL_NAME(XDGAKeyEvent); + +typedef struct { + int type; + unsigned long serial; + Display *display; + int screen; + Time time; + unsigned int state; + int dx; + int dy; +} SDL_NAME(XDGAMotionEvent); + +typedef union { + int type; + SDL_NAME(XDGAButtonEvent) xbutton; + SDL_NAME(XDGAKeyEvent) xkey; + SDL_NAME(XDGAMotionEvent) xmotion; + long pad[24]; +} SDL_NAME(XDGAEvent); + +Bool SDL_NAME(XDGAQueryExtension)( + Display *dpy, + int *eventBase, + int *erroBase +); + +Bool SDL_NAME(XDGAQueryVersion)( + Display *dpy, + int *majorVersion, + int *minorVersion +); + +SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)( + Display *dpy, + int screen, + int *num +); + +SDL_NAME(XDGADevice)* SDL_NAME(XDGASetMode)( + Display *dpy, + int screen, + int mode +); + +Bool SDL_NAME(XDGAOpenFramebuffer)( + Display *dpy, + int screen +); + +void SDL_NAME(XDGACloseFramebuffer)( + Display *dpy, + int screen +); + +void SDL_NAME(XDGASetViewport)( + Display *dpy, + int screen, + int x, + int y, + int flags +); + +void SDL_NAME(XDGAInstallColormap)( + Display *dpy, + int screen, + Colormap cmap +); + +Colormap SDL_NAME(XDGACreateColormap)( + Display *dpy, + int screen, + SDL_NAME(XDGADevice) *device, + int alloc +); + +void SDL_NAME(XDGASelectInput)( + Display *dpy, + int screen, + long event_mask +); + +void SDL_NAME(XDGAFillRectangle)( + Display *dpy, + int screen, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned long color +); + + +void SDL_NAME(XDGACopyArea)( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty +); + + +void SDL_NAME(XDGACopyTransparentArea)( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty, + unsigned long key +); + +int SDL_NAME(XDGAGetViewportStatus)( + Display *dpy, + int screen +); + +void SDL_NAME(XDGASync)( + Display *dpy, + int screen +); + +Bool SDL_NAME(XDGASetClientVersion)( + Display *dpy +); + +void SDL_NAME(XDGAChangePixmapMode)( + Display *dpy, + int screen, + int *x, + int *y, + int mode +); + + +void SDL_NAME(XDGAKeyEventToXKeyEvent)(SDL_NAME(XDGAKeyEvent)* dk, XKeyEvent* xk); + + +_XFUNCPROTOEND +#endif /* _XF86DGA_SERVER_ */ +#endif /* _XF86DGA_H_ */ diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1.h new file mode 100644 index 0000000000..4a49e9f385 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1.h @@ -0,0 +1,169 @@ +/* $XFree86: xc/include/extensions/xf86dga1.h,v 1.2 1999/04/17 07:05:41 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995 XFree86 Inc + +*/ + +/************************************************************************ + + THIS IS THE OLD DGA API AND IS OBSOLETE. PLEASE DO NOT USE IT ANYMORE + +************************************************************************/ + +#ifndef _XF86DGA1_H_ +#define _XF86DGA1_H_ + +#include +#include "SDL_name.h" + +#define X_XF86DGAQueryVersion 0 +#define X_XF86DGAGetVideoLL 1 +#define X_XF86DGADirectVideo 2 +#define X_XF86DGAGetViewPortSize 3 +#define X_XF86DGASetViewPort 4 +#define X_XF86DGAGetVidPage 5 +#define X_XF86DGASetVidPage 6 +#define X_XF86DGAInstallColormap 7 +#define X_XF86DGAQueryDirectVideo 8 +#define X_XF86DGAViewPortChanged 9 + +#define XF86DGADirectPresent 0x0001 +#define XF86DGADirectGraphics 0x0002 +#define XF86DGADirectMouse 0x0004 +#define XF86DGADirectKeyb 0x0008 +#define XF86DGAHasColormap 0x0100 +#define XF86DGADirectColormap 0x0200 + + + + +#ifndef _XF86DGA_SERVER_ + +_XFUNCPROTOBEGIN + +Bool SDL_NAME(XF86DGAQueryVersion)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int* /* majorVersion */, + int* /* minorVersion */ +#endif +); + +Bool SDL_NAME(XF86DGAQueryExtension)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int* /* event_base */, + int* /* error_base */ +#endif +); + +Status SDL_NAME(XF86DGAGetVideoLL)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int * /* base addr */, + int * /* width */, + int * /* bank_size */, + int * /* ram_size */ +#endif +); + +Status SDL_NAME(XF86DGAGetVideo)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + char ** /* base addr */, + int * /* width */, + int * /* bank_size */, + int * /* ram_size */ +#endif +); + +Status SDL_NAME(XF86DGADirectVideo)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int /* enable */ +#endif +); + +Status SDL_NAME(XF86DGADirectVideoLL)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int /* enable */ +#endif +); + +Status SDL_NAME(XF86DGAGetViewPortSize)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int * /* width */, + int * /* height */ +#endif +); + +Status SDL_NAME(XF86DGASetViewPort)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int x /* X */, + int y /* Y */ +#endif +); + +Status SDL_NAME(XF86DGAGetVidPage)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int * /* vid page */ +#endif +); + +Status SDL_NAME(XF86DGASetVidPage)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int /* vid page */ +#endif +); + +Status SDL_NAME(XF86DGAInstallColormap)( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + Colormap /*Colormap */ +#endif +); + +int SDL_NAME(XF86DGAForkApp)( +#if NeedFunctionPrototypes + int screen +#endif +); + +Status SDL_NAME(XF86DGAQueryDirectVideo)( +#if NeedFunctionPrototypes + Display * /* dpy */, + int /* screen */, + int * /* flags */ +#endif +); + +Bool SDL_NAME(XF86DGAViewPortChanged)( +#if NeedFunctionPrototypes + Display * /* dpy */, + int /* screen */, + int /* n */ +#endif +); + + +_XFUNCPROTOEND + +#endif /* _XF86DGA_SERVER_ */ + +#endif /* _XF86DGA1_H_ */ diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1str.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1str.h new file mode 100644 index 0000000000..5695fbd13b --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86dga1str.h @@ -0,0 +1,194 @@ +/* $XFree86: xc/include/extensions/xf86dga1str.h,v 1.2 1999/05/03 12:15:37 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995 XFree86 Inc. + +*/ + +#ifndef _XF86DGASTR1_H_ +#define _XF86DGASTR1_H_ + +typedef struct _XF86DGAQueryVersion { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_DGAQueryVersion */ + CARD16 length B16; +} xXF86DGAQueryVersionReq; +#define sz_xXF86DGAQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DGA protocol */ + CARD16 minorVersion B16; /* minor version of DGA protocol */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DGAQueryVersionReply; +#define sz_xXF86DGAQueryVersionReply 32 + +typedef struct _XF86DGAGetVideoLL { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGAGetVideoLL */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86DGAGetVideoLLReq; +#define sz_xXF86DGAGetVideoLLReq 8 + +typedef struct _XF86DGAInstallColormap{ + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 pad2; + CARD32 id B32; /* colormap. */ +} xXF86DGAInstallColormapReq; +#define sz_xXF86DGAInstallColormapReq 12 + + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 offset B32; + CARD32 width B32; + CARD32 bank_size B32; + CARD32 ram_size B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86DGAGetVideoLLReply; +#define sz_xXF86DGAGetVideoLLReply 32 + +typedef struct _XF86DGADirectVideo { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGADirectVideo */ + CARD16 length B16; + CARD16 screen B16; + CARD16 enable B16; +} xXF86DGADirectVideoReq; +#define sz_xXF86DGADirectVideoReq 8 + + +typedef struct _XF86DGAGetViewPortSize { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGAGetViewPort */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86DGAGetViewPortSizeReq; +#define sz_xXF86DGAGetViewPortSizeReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 width B32; + CARD32 height B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86DGAGetViewPortSizeReply; +#define sz_xXF86DGAGetViewPortSizeReply 32 + +typedef struct _XF86DGASetViewPort { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGASetViewPort */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; + CARD32 x B32; + CARD32 y B32; +} xXF86DGASetViewPortReq; +#define sz_xXF86DGASetViewPortReq 16 + +typedef struct _XF86DGAGetVidPage { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGAGetVidPage */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86DGAGetVidPageReq; +#define sz_xXF86DGAGetVidPageReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 vpage B32; + CARD32 pad B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86DGAGetVidPageReply; +#define sz_xXF86DGAGetVidPageReply 32 + + +typedef struct _XF86DGASetVidPage { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_XF86DGASetVidPage */ + CARD16 length B16; + CARD16 screen B16; + CARD16 vpage B16; +} xXF86DGASetVidPageReq; +#define sz_xXF86DGASetVidPageReq 8 + + +typedef struct _XF86DGAQueryDirectVideo { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_DGAQueryVersion */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86DGAQueryDirectVideoReq; +#define sz_xXF86DGAQueryDirectVideoReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 pad B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86DGAQueryDirectVideoReply; +#define sz_xXF86DGAQueryDirectVideoReply 32 + + +typedef struct _XF86DGAViewPortChanged { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_DGAQueryVersion */ + CARD16 length B16; + CARD16 screen B16; + CARD16 n B16; +} xXF86DGAViewPortChangedReq; +#define sz_xXF86DGAViewPortChangedReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 result B32; + CARD32 pad B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86DGAViewPortChangedReply; +#define sz_xXF86DGAViewPortChangedReply 32 + +#endif /* _XF86DGASTR1_H_ */ + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86dgastr.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86dgastr.h new file mode 100644 index 0000000000..b249feb3c6 --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86dgastr.h @@ -0,0 +1,344 @@ +/* $XFree86: xc/include/extensions/xf86dgastr.h,v 3.14 2001/08/01 00:44:36 tsi Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995 XFree86 Inc. + +*/ + +#ifndef _XF86DGASTR_H_ +#define _XF86DGASTR_H_ + +#include "xf86dga1str.h" + +#define XF86DGANAME "XFree86-DGA" + +#define XDGA_MAJOR_VERSION 2 /* current version numbers */ +#define XDGA_MINOR_VERSION 0 + + +typedef struct _XDGAQueryVersion { + CARD8 reqType; /* always DGAReqCode */ + CARD8 dgaReqType; /* always X_DGAQueryVersion */ + CARD16 length B16; +} xXDGAQueryVersionReq; +#define sz_xXDGAQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DGA protocol */ + CARD16 minorVersion B16; /* minor version of DGA protocol */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXDGAQueryVersionReply; +#define sz_xXDGAQueryVersionReply 32 + +typedef struct _XDGAQueryModes { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; +} xXDGAQueryModesReq; +#define sz_xXDGAQueryModesReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 number B32; /* number of modes available */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXDGAQueryModesReply; +#define sz_xXDGAQueryModesReply 32 + + +typedef struct _XDGASetMode { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 mode B32; /* mode number to init */ + CARD32 pid B32; /* Pixmap descriptor */ +} xXDGASetModeReq; +#define sz_xXDGASetModeReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 offset B32; /* offset into framebuffer map */ + CARD32 flags B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXDGASetModeReply; +#define sz_xXDGASetModeReply 32 + +typedef struct { + CARD8 byte_order; + CARD8 depth; + CARD16 num B16; + CARD16 bpp B16; + CARD16 name_size B16; + CARD32 vsync_num B32; + CARD32 vsync_den B32; + CARD32 flags B32; + CARD16 image_width B16; + CARD16 image_height B16; + CARD16 pixmap_width B16; + CARD16 pixmap_height B16; + CARD32 bytes_per_scanline B32; + CARD32 red_mask B32; + CARD32 green_mask B32; + CARD32 blue_mask B32; + CARD16 visual_class B16; + CARD16 pad1 B16; + CARD16 viewport_width B16; + CARD16 viewport_height B16; + CARD16 viewport_xstep B16; + CARD16 viewport_ystep B16; + CARD16 viewport_xmax B16; + CARD16 viewport_ymax B16; + CARD32 viewport_flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; +} xXDGAModeInfo; +#define sz_xXDGAModeInfo 72 + +typedef struct _XDGAOpenFramebuffer { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; +} xXDGAOpenFramebufferReq; +#define sz_xXDGAOpenFramebufferReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* device name size if there is one */ + CARD32 mem1 B32; /* physical memory */ + CARD32 mem2 B32; /* spillover for _alpha_ */ + CARD32 size B32; /* size of map in bytes */ + CARD32 offset B32; /* optional offset into device */ + CARD32 extra B32; /* extra info associated with the map */ + CARD32 pad2 B32; +} xXDGAOpenFramebufferReply; +#define sz_xXDGAOpenFramebufferReply 32 + + +typedef struct _XDGACloseFramebuffer { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; +} xXDGACloseFramebufferReq; +#define sz_xXDGACloseFramebufferReq 8 + + +typedef struct _XDGASetViewport { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 x B16; + CARD16 y B16; + CARD32 flags B32; +} xXDGASetViewportReq; +#define sz_xXDGASetViewportReq 16 + + +typedef struct _XDGAInstallColormap { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 cmap B32; +} xXDGAInstallColormapReq; +#define sz_xXDGAInstallColormapReq 12 + +typedef struct _XDGASelectInput { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 mask B32; +} xXDGASelectInputReq; +#define sz_xXDGASelectInputReq 12 + +typedef struct _XDGAFillRectangle { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 x B16; + CARD16 y B16; + CARD16 width B16; + CARD16 height B16; + CARD32 color B32; +} xXDGAFillRectangleReq; +#define sz_xXDGAFillRectangleReq 20 + + +typedef struct _XDGACopyArea { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 srcx B16; + CARD16 srcy B16; + CARD16 width B16; + CARD16 height B16; + CARD16 dstx B16; + CARD16 dsty B16; +} xXDGACopyAreaReq; +#define sz_xXDGACopyAreaReq 20 + +typedef struct _XDGACopyTransparentArea { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 srcx B16; + CARD16 srcy B16; + CARD16 width B16; + CARD16 height B16; + CARD16 dstx B16; + CARD16 dsty B16; + CARD32 key B32; +} xXDGACopyTransparentAreaReq; +#define sz_xXDGACopyTransparentAreaReq 24 + + +typedef struct _XDGAGetViewportStatus { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; +} xXDGAGetViewportStatusReq; +#define sz_xXDGAGetViewportStatusReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 status B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXDGAGetViewportStatusReply; +#define sz_xXDGAGetViewportStatusReply 32 + +typedef struct _XDGASync { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; +} xXDGASyncReq; +#define sz_xXDGASyncReq 8 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXDGASyncReply; +#define sz_xXDGASyncReply 32 + +typedef struct _XDGASetClientVersion { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD16 major B16; + CARD16 minor B16; +} xXDGASetClientVersionReq; +#define sz_xXDGASetClientVersionReq 8 + + +typedef struct { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 x B16; + CARD16 y B16; + CARD32 flags B32; +} xXDGAChangePixmapModeReq; +#define sz_xXDGAChangePixmapModeReq 16 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 x B16; + CARD16 y B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXDGAChangePixmapModeReply; +#define sz_xXDGAChangePixmapModeReply 32 + +typedef struct _XDGACreateColormap { + CARD8 reqType; + CARD8 dgaReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 id B32; + CARD32 mode B32; + CARD8 alloc; + CARD8 pad1; + CARD16 pad2; +} xXDGACreateColormapReq; +#define sz_xXDGACreateColormapReq 20 + + +typedef struct { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + CARD32 pad0 B32; + CARD32 time B32; + INT16 dx B16; + INT16 dy B16; + INT16 screen B16; + CARD16 state B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + } event; + } u; +} dgaEvent; + + +#endif /* _XF86DGASTR_H_ */ + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86vmode.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86vmode.h new file mode 100644 index 0000000000..eb56c0e8da --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86vmode.h @@ -0,0 +1,314 @@ +/* $XFree86: xc/include/extensions/xf86vmode.h,v 3.30 2001/05/07 20:09:50 mvojkovi Exp $ */ +/* + +Copyright 1995 Kaleb S. KEITHLEY + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Kaleb S. KEITHLEY +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +from Kaleb S. KEITHLEY + +*/ +/* $Xorg: xf86vmode.h,v 1.3 2000/08/18 04:05:46 coskrey Exp $ */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ + +#ifndef _XF86VIDMODE_H_ +#define _XF86VIDMODE_H_ + +#include +#include +#include "SDL_name.h" + +#define X_XF86VidModeQueryVersion 0 +#define X_XF86VidModeGetModeLine 1 +#define X_XF86VidModeModModeLine 2 +#define X_XF86VidModeSwitchMode 3 +#define X_XF86VidModeGetMonitor 4 +#define X_XF86VidModeLockModeSwitch 5 +#define X_XF86VidModeGetAllModeLines 6 +#define X_XF86VidModeAddModeLine 7 +#define X_XF86VidModeDeleteModeLine 8 +#define X_XF86VidModeValidateModeLine 9 +#define X_XF86VidModeSwitchToMode 10 +#define X_XF86VidModeGetViewPort 11 +#define X_XF86VidModeSetViewPort 12 +/* new for version 2.x of this extension */ +#define X_XF86VidModeGetDotClocks 13 +#define X_XF86VidModeSetClientVersion 14 +#define X_XF86VidModeSetGamma 15 +#define X_XF86VidModeGetGamma 16 +#define X_XF86VidModeGetGammaRamp 17 +#define X_XF86VidModeSetGammaRamp 18 +#define X_XF86VidModeGetGammaRampSize 19 + +#define CLKFLAG_PROGRAMABLE 1 + +#ifdef XF86VIDMODE_EVENTS +#define XF86VidModeNotify 0 +#define XF86VidModeNumberEvents (XF86VidModeNotify + 1) + +#define XF86VidModeNotifyMask 0x00000001 + +#define XF86VidModeNonEvent 0 +#define XF86VidModeModeChange 1 +#else +#define XF86VidModeNumberEvents 0 +#endif + +#define XF86VidModeBadClock 0 +#define XF86VidModeBadHTimings 1 +#define XF86VidModeBadVTimings 2 +#define XF86VidModeModeUnsuitable 3 +#define XF86VidModeExtensionDisabled 4 +#define XF86VidModeClientNotLocal 5 +#define XF86VidModeZoomLocked 6 +#define XF86VidModeNumberErrors (XF86VidModeZoomLocked + 1) + +#ifndef _XF86VIDMODE_SERVER_ + +typedef struct { + unsigned short hdisplay; + unsigned short hsyncstart; + unsigned short hsyncend; + unsigned short htotal; + unsigned short hskew; + unsigned short vdisplay; + unsigned short vsyncstart; + unsigned short vsyncend; + unsigned short vtotal; + unsigned int flags; + int privsize; +#if defined(__cplusplus) || defined(c_plusplus) + /* private is a C++ reserved word */ + INT32 *c_private; +#else + INT32 *private; +#endif +} SDL_NAME(XF86VidModeModeLine); + +typedef struct { + unsigned int dotclock; + unsigned short hdisplay; + unsigned short hsyncstart; + unsigned short hsyncend; + unsigned short htotal; + unsigned short hskew; + unsigned short vdisplay; + unsigned short vsyncstart; + unsigned short vsyncend; + unsigned short vtotal; + unsigned int flags; + int privsize; +#if defined(__cplusplus) || defined(c_plusplus) + /* private is a C++ reserved word */ + INT32 *c_private; +#else + INT32 *private; +#endif +} SDL_NAME(XF86VidModeModeInfo); + +typedef struct { + float hi; + float lo; +} SDL_NAME(XF86VidModeSyncRange); + +typedef struct { + char* vendor; + char* model; + float EMPTY; + unsigned char nhsync; + SDL_NAME(XF86VidModeSyncRange)* hsync; + unsigned char nvsync; + SDL_NAME(XF86VidModeSyncRange)* vsync; +} SDL_NAME(XF86VidModeMonitor); + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent req */ + Display *display; /* Display the event was read from */ + Window root; /* root window of event screen */ + int state; /* What happened */ + int kind; /* What happened */ + Bool forced; /* extents of new region */ + Time time; /* event timestamp */ +} SDL_NAME(XF86VidModeNotifyEvent); + +typedef struct { + float red; /* Red Gamma value */ + float green; /* Green Gamma value */ + float blue; /* Blue Gamma value */ +} SDL_NAME(XF86VidModeGamma); + + +#define SDL_XF86VidModeSelectNextMode(disp, scr) \ + SDL_NAME(XF86VidModeSwitchMode)(disp, scr, 1) +#define SDL_XF86VidModeSelectPrevMode(disp, scr) \ + SDL_NAME(XF86VidModeSwitchMode)(disp, scr, -1) + +_XFUNCPROTOBEGIN + +Bool SDL_NAME(XF86VidModeQueryVersion)( + Display* /* dpy */, + int* /* majorVersion */, + int* /* minorVersion */ +); + +Bool SDL_NAME(XF86VidModeQueryExtension)( + Display* /* dpy */, + int* /* event_base */, + int* /* error_base */ +); + +Bool SDL_NAME(XF86VidModeSetClientVersion)( + Display* /* dpy */ +); + +Bool SDL_NAME(XF86VidModeGetModeLine)( + Display* /* dpy */, + int /* screen */, + int* /* dotclock */, + SDL_NAME(XF86VidModeModeLine)* /* modeline */ +); + +Bool SDL_NAME(XF86VidModeGetAllModeLines)( + Display* /* dpy */, + int /* screen */, + int* /* modecount */, + SDL_NAME(XF86VidModeModeInfo)*** /* modelinesPtr */ +); + +Bool SDL_NAME(XF86VidModeAddModeLine)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeModeInfo)* /* new modeline */, + SDL_NAME(XF86VidModeModeInfo)* /* after modeline */ +); + +Bool SDL_NAME(XF86VidModeDeleteModeLine)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeModeInfo)* /* modeline */ +); + +Bool SDL_NAME(XF86VidModeModModeLine)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeModeLine)* /* modeline */ +); + +Status SDL_NAME(XF86VidModeValidateModeLine)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeModeInfo)* /* modeline */ +); + +Bool SDL_NAME(XF86VidModeSwitchMode)( + Display* /* dpy */, + int /* screen */, + int /* zoom */ +); + +Bool SDL_NAME(XF86VidModeSwitchToMode)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeModeInfo)* /* modeline */ +); + +Bool SDL_NAME(XF86VidModeLockModeSwitch)( + Display* /* dpy */, + int /* screen */, + int /* lock */ +); + +Bool SDL_NAME(XF86VidModeGetMonitor)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeMonitor)* /* monitor */ +); + +Bool SDL_NAME(XF86VidModeGetViewPort)( + Display* /* dpy */, + int /* screen */, + int* /* x return */, + int* /* y return */ +); + +Bool SDL_NAME(XF86VidModeSetViewPort)( + Display* /* dpy */, + int /* screen */, + int /* x */, + int /* y */ +); + +Bool SDL_NAME(XF86VidModeGetDotClocks)( + Display* /* dpy */, + int /* screen */, + int* /* flags return */, + int* /* number of clocks return */, + int* /* max dot clock return */, + int** /* clocks return */ +); + +Bool SDL_NAME(XF86VidModeGetGamma)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeGamma)* /* Gamma */ +); + +Bool SDL_NAME(XF86VidModeSetGamma)( + Display* /* dpy */, + int /* screen */, + SDL_NAME(XF86VidModeGamma)* /* Gamma */ +); + +Bool SDL_NAME(XF86VidModeSetGammaRamp)( + Display* /* dpy */, + int /* screen */, + int /* size */, + unsigned short* /* red array */, + unsigned short* /* green array */, + unsigned short* /* blue array */ +); + +Bool SDL_NAME(XF86VidModeGetGammaRamp)( + Display* /* dpy */, + int /* screen */, + int /* size */, + unsigned short* /* red array */, + unsigned short* /* green array */, + unsigned short* /* blue array */ +); + +Bool SDL_NAME(XF86VidModeGetGammaRampSize)( + Display* /* dpy */, + int /* screen */, + int* /* size */ +); + + +_XFUNCPROTOEND + +#endif + +#endif diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xf86vmstr.h b/apps/plugins/sdl/src/video/Xext/extensions/xf86vmstr.h new file mode 100644 index 0000000000..0c3078d5aa --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xf86vmstr.h @@ -0,0 +1,546 @@ +/* $XFree86: xc/include/extensions/xf86vmstr.h,v 3.27 2001/08/01 00:44:36 tsi Exp $ */ +/* + +Copyright 1995 Kaleb S. KEITHLEY + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES +OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Kaleb S. KEITHLEY +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +from Kaleb S. KEITHLEY + +*/ +/* $Xorg: xf86vmstr.h,v 1.3 2000/08/18 04:05:46 coskrey Exp $ */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ + +#ifndef _XF86VIDMODESTR_H_ +#define _XF86VIDMODESTR_H_ + +#include "xf86vmode.h" + +#define XF86VIDMODENAME "XFree86-VidModeExtension" + +#define XF86VIDMODE_MAJOR_VERSION 2 /* current version numbers */ +#define XF86VIDMODE_MINOR_VERSION 1 +/* + * major version 0 == uses parameter-to-wire functions in XFree86 libXxf86vm. + * major version 1 == uses parameter-to-wire functions hard-coded in xvidtune + * client. + * major version 2 == uses new protocol version in XFree86 4.0. + */ + +typedef struct _XF86VidModeQueryVersion { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeQueryVersion */ + CARD16 length B16; +} xXF86VidModeQueryVersionReq; +#define sz_xXF86VidModeQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of XF86VidMode */ + CARD16 minorVersion B16; /* minor version of XF86VidMode */ + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86VidModeQueryVersionReply; +#define sz_xXF86VidModeQueryVersionReply 32 + +typedef struct _XF86VidModeGetModeLine { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86VidModeGetModeLineReq, + xXF86VidModeGetAllModeLinesReq, + xXF86VidModeGetMonitorReq, + xXF86VidModeGetViewPortReq, + xXF86VidModeGetDotClocksReq; +#define sz_xXF86VidModeGetModeLineReq 8 +#define sz_xXF86VidModeGetAllModeLinesReq 8 +#define sz_xXF86VidModeGetMonitorReq 8 +#define sz_xXF86VidModeGetViewPortReq 8 +#define sz_xXF86VidModeGetDotClocksReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 hskew B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD16 pad2 B16; + CARD32 flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; + CARD32 reserved3 B32; + CARD32 privsize B32; +} xXF86VidModeGetModeLineReply; +#define sz_xXF86VidModeGetModeLineReply 52 + +/* 0.x version */ +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD32 flags B32; + CARD32 privsize B32; +} xXF86OldVidModeGetModeLineReply; +#define sz_xXF86OldVidModeGetModeLineReply 36 + +typedef struct { + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD32 hskew B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD16 pad1 B16; + CARD32 flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; + CARD32 reserved3 B32; + CARD32 privsize B32; +} xXF86VidModeModeInfo; + +/* 0.x version */ +typedef struct { + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD32 flags B32; + CARD32 privsize B32; +} xXF86OldVidModeModeInfo; + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 modecount B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86VidModeGetAllModeLinesReply; +#define sz_xXF86VidModeGetAllModeLinesReply 32 + +typedef struct _XF86VidModeAddModeLine { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeAddMode */ + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 hskew B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD16 pad1 B16; + CARD32 flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; + CARD32 reserved3 B32; + CARD32 privsize B32; + CARD32 after_dotclock B32; + CARD16 after_hdisplay B16; + CARD16 after_hsyncstart B16; + CARD16 after_hsyncend B16; + CARD16 after_htotal B16; + CARD16 after_hskew B16; + CARD16 after_vdisplay B16; + CARD16 after_vsyncstart B16; + CARD16 after_vsyncend B16; + CARD16 after_vtotal B16; + CARD16 pad2 B16; + CARD32 after_flags B32; + CARD32 reserved4 B32; + CARD32 reserved5 B32; + CARD32 reserved6 B32; +} xXF86VidModeAddModeLineReq; +#define sz_xXF86VidModeAddModeLineReq 92 + +/* 0.x version */ +typedef struct _XF86OldVidModeAddModeLine { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeAddMode */ + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD32 flags B32; + CARD32 privsize B32; + CARD32 after_dotclock B32; + CARD16 after_hdisplay B16; + CARD16 after_hsyncstart B16; + CARD16 after_hsyncend B16; + CARD16 after_htotal B16; + CARD16 after_vdisplay B16; + CARD16 after_vsyncstart B16; + CARD16 after_vsyncend B16; + CARD16 after_vtotal B16; + CARD32 after_flags B32; +} xXF86OldVidModeAddModeLineReq; +#define sz_xXF86OldVidModeAddModeLineReq 60 + +typedef struct _XF86VidModeModModeLine { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeModModeLine */ + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 hskew B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD16 pad1 B16; + CARD32 flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; + CARD32 reserved3 B32; + CARD32 privsize B32; +} xXF86VidModeModModeLineReq; +#define sz_xXF86VidModeModModeLineReq 48 + +/* 0.x version */ +typedef struct _XF86OldVidModeModModeLine { + CARD8 reqType; /* always XF86OldVidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86OldVidModeModModeLine */ + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD32 flags B32; + CARD32 privsize B32; +} xXF86OldVidModeModModeLineReq; +#define sz_xXF86OldVidModeModModeLineReq 32 + +typedef struct _XF86VidModeValidateModeLine { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 hskew B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD16 pad1 B16; + CARD32 flags B32; + CARD32 reserved1 B32; + CARD32 reserved2 B32; + CARD32 reserved3 B32; + CARD32 privsize B32; +} xXF86VidModeDeleteModeLineReq, + xXF86VidModeValidateModeLineReq, + xXF86VidModeSwitchToModeReq; +#define sz_xXF86VidModeDeleteModeLineReq 52 +#define sz_xXF86VidModeValidateModeLineReq 52 +#define sz_xXF86VidModeSwitchToModeReq 52 + +/* 0.x version */ +typedef struct _XF86OldVidModeValidateModeLine { + CARD8 reqType; /* always XF86OldVidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD32 screen B32; /* could be CARD16 but need the pad */ + CARD32 dotclock B32; + CARD16 hdisplay B16; + CARD16 hsyncstart B16; + CARD16 hsyncend B16; + CARD16 htotal B16; + CARD16 vdisplay B16; + CARD16 vsyncstart B16; + CARD16 vsyncend B16; + CARD16 vtotal B16; + CARD32 flags B32; + CARD32 privsize B32; +} xXF86OldVidModeDeleteModeLineReq, + xXF86OldVidModeValidateModeLineReq, + xXF86OldVidModeSwitchToModeReq; +#define sz_xXF86OldVidModeDeleteModeLineReq 36 +#define sz_xXF86OldVidModeValidateModeLineReq 36 +#define sz_xXF86OldVidModeSwitchToModeReq 36 + +typedef struct _XF86VidModeSwitchMode { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeSwitchMode */ + CARD16 length B16; + CARD16 screen B16; + CARD16 zoom B16; +} xXF86VidModeSwitchModeReq; +#define sz_xXF86VidModeSwitchModeReq 8 + +typedef struct _XF86VidModeLockModeSwitch { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeLockModeSwitch */ + CARD16 length B16; + CARD16 screen B16; + CARD16 lock B16; +} xXF86VidModeLockModeSwitchReq; +#define sz_xXF86VidModeLockModeSwitchReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 status B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86VidModeValidateModeLineReply; +#define sz_xXF86VidModeValidateModeLineReply 32 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 vendorLength; + CARD8 modelLength; + CARD8 nhsync; + CARD8 nvsync; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86VidModeGetMonitorReply; +#define sz_xXF86VidModeGetMonitorReply 32 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 x B32; + CARD32 y B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86VidModeGetViewPortReply; +#define sz_xXF86VidModeGetViewPortReply 32 + +typedef struct _XF86VidModeSetViewPort { + CARD8 reqType; /* always VidModeReqCode */ + CARD8 xf86vidmodeReqType; /* always X_XF86VidModeSetViewPort */ + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; + CARD32 x B32; + CARD32 y B32; +} xXF86VidModeSetViewPortReq; +#define sz_xXF86VidModeSetViewPortReq 16 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 clocks B32; + CARD32 maxclocks B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xXF86VidModeGetDotClocksReply; +#define sz_xXF86VidModeGetDotClocksReply 32 + +typedef struct _XF86VidModeSetClientVersion { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 major B16; + CARD16 minor B16; +} xXF86VidModeSetClientVersionReq; +#define sz_xXF86VidModeSetClientVersionReq 8 + +typedef struct _XF86VidModeGetGamma { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86VidModeGetGammaReq; +#define sz_xXF86VidModeGetGammaReq 32 + +typedef struct { + BYTE type; + BOOL pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 red B32; + CARD32 green B32; + CARD32 blue B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xXF86VidModeGetGammaReply; +#define sz_xXF86VidModeGetGammaReply 32 + +typedef struct _XF86VidModeSetGamma { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; + CARD32 red B32; + CARD32 green B32; + CARD32 blue B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xXF86VidModeSetGammaReq; +#define sz_xXF86VidModeSetGammaReq 32 + + +typedef struct _XF86VidModeSetGammaRamp { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 size B16; +} xXF86VidModeSetGammaRampReq; +#define sz_xXF86VidModeSetGammaRampReq 8 + +typedef struct _XF86VidModeGetGammaRamp { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 size B16; +} xXF86VidModeGetGammaRampReq; +#define sz_xXF86VidModeGetGammaRampReq 8 + +typedef struct { + BYTE type; + BOOL pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad0 B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86VidModeGetGammaRampReply; +#define sz_xXF86VidModeGetGammaRampReply 32 + +typedef struct _XF86VidModeGetGammaRampSize { + CARD8 reqType; /* always XF86VidModeReqCode */ + CARD8 xf86vidmodeReqType; + CARD16 length B16; + CARD16 screen B16; + CARD16 pad B16; +} xXF86VidModeGetGammaRampSizeReq; +#define sz_xXF86VidModeGetGammaRampSizeReq 8 + +typedef struct { + BYTE type; + BOOL pad; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 size B16; + CARD16 pad0 B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xXF86VidModeGetGammaRampSizeReply; +#define sz_xXF86VidModeGetGammaRampSizeReply 32 + + +#endif /* _XF86VIDMODESTR_H_ */ + diff --git a/apps/plugins/sdl/src/video/Xext/extensions/xme.h b/apps/plugins/sdl/src/video/Xext/extensions/xme.h new file mode 100644 index 0000000000..f550623c9f --- /dev/null +++ b/apps/plugins/sdl/src/video/Xext/extensions/xme.h @@ -0,0 +1,45 @@ +/* + * Copyright 1993-2001 by Xi Graphics, Inc. + * All Rights Reserved. + * + * Please see the LICENSE file accompanying this distribution for licensing + * information. + * + * Please send any bug fixes and modifications to src@xig.com. + * + * $XiGId: xme.h,v 1.1.1.1 2001/11/19 19:01:10 jon Exp $ + * + */ + + +#ifndef _XME_H_INCLUDED +#define _XME_H_INCLUDED + +typedef struct { + short x; + short y; + unsigned short w; + unsigned short h; +} XiGMiscViewInfo; + +typedef struct { + unsigned short width; + unsigned short height; + int refresh; +} XiGMiscResolutionInfo; + +extern Bool XiGMiscQueryVersion(Display *dpy, int *major, int *minor); +extern int XiGMiscQueryViews(Display *dpy, int screen, + XiGMiscViewInfo **pviews); +extern int XiGMiscQueryResolutions(Display *dpy, int screen, int view, + int *pactive, + XiGMiscResolutionInfo **presolutions); +extern void XiGMiscChangeResolution(Display *dpy, int screen, int view, + int width, int height, int refresh); + +/* SDL addition from Ryan: free memory used by xme. */ +extern void XiGMiscDestroy(void); + +#endif /* _XME_H_INCLUDED */ + + diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aaevents.c b/apps/plugins/sdl/src/video/aalib/SDL_aaevents.c new file mode 100644 index 0000000000..a26ab2d0e1 --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aaevents.c @@ -0,0 +1,202 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Handle the event stream, converting AA events into SDL events */ + +#include + +#include + +#include "SDL.h" +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" +#include "SDL_aavideo.h" +#include "SDL_aaevents_c.h" + +/* The translation tables from a console scancode to a SDL keysym */ +static SDLKey keymap[401]; + +static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); + + +void AA_PumpEvents(_THIS) +{ + int posted = 0; + int mouse_button, mouse_x, mouse_y; + int evt; + SDL_keysym keysym; + + static int prev_button = -1, prev_x = -1, prev_y = -1; + + if( ! this->screen ) /* Wait till we got the screen initialized */ + return; + + do { + posted = 0; + /* Gather events */ + + /* Get mouse status */ + SDL_mutexP(AA_mutex); + aa_getmouse (AA_context, &mouse_x, &mouse_y, &mouse_button); + SDL_mutexV(AA_mutex); + mouse_x = mouse_x * this->screen->w / aa_scrwidth (AA_context); + mouse_y = mouse_y * this->screen->h / aa_scrheight (AA_context); + + /* Compare against previous state and generate events */ + if( prev_button != mouse_button ) { + if( mouse_button & AA_BUTTON1 ) { + if ( ! (prev_button & AA_BUTTON1) ) { + posted += SDL_PrivateMouseButton(SDL_PRESSED, 1, 0, 0); + } + } else { + if ( prev_button & AA_BUTTON1 ) { + posted += SDL_PrivateMouseButton(SDL_RELEASED, 1, 0, 0); + } + } + if( mouse_button & AA_BUTTON2 ) { + if ( ! (prev_button & AA_BUTTON2) ) { + posted += SDL_PrivateMouseButton(SDL_PRESSED, 2, 0, 0); + } + } else { + if ( prev_button & AA_BUTTON2 ) { + posted += SDL_PrivateMouseButton(SDL_RELEASED, 2, 0, 0); + } + } + if( mouse_button & AA_BUTTON3 ) { + if ( ! (prev_button & AA_BUTTON3) ) { + posted += SDL_PrivateMouseButton(SDL_PRESSED, 3, 0, 0); + } + } else { + if ( prev_button & AA_BUTTON3 ) { + posted += SDL_PrivateMouseButton(SDL_RELEASED, 3, 0, 0); + } + } + } + if ( prev_x != mouse_x || prev_y != mouse_y ) { + posted += SDL_PrivateMouseMotion(0, 0, mouse_x, mouse_y); + } + + prev_button = mouse_button; + prev_x = mouse_x; prev_y = mouse_y; + + /* Get keyboard event */ + SDL_mutexP(AA_mutex); + evt = aa_getevent(AA_context, 0); + SDL_mutexV(AA_mutex); + if ( (evt > AA_NONE) && (evt < AA_RELEASE) && (evt != AA_MOUSE) && (evt != AA_RESIZE) ) { + /* Key pressed */ +/* printf("Key pressed: %d (%c)\n", evt, evt); */ + posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(evt, &keysym)); + } else if ( evt >= AA_RELEASE ) { + /* Key released */ + evt &= ~AA_RELEASE; +/* printf("Key released: %d (%c)\n", evt, evt); */ + posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(evt, &keysym)); + } + } while ( posted ); +} + +void AA_InitOSKeymap(_THIS) +{ + int i; + static const char *std_keys = " 01234567890&#'()_-|$*+-=/\\:;.,!?<>{}[]@~%^\x9"; + const char *std; + + /* Initialize the AAlib key translation table */ + for ( i=0; i= SDL_arraysize(keymap) ) + scancode = AA_UNKNOWN; + + /* Set the keysym information */ + keysym->scancode = scancode; + keysym->sym = keymap[scancode]; + keysym->mod = KMOD_NONE; + + /* If UNICODE is on, get the UNICODE value for the key */ + keysym->unicode = 0; + if ( SDL_TranslateUNICODE ) { + /* Populate the unicode field with the ASCII value */ + keysym->unicode = scancode; + } + return(keysym); +} diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aaevents_c.h b/apps/plugins/sdl/src/video/aalib/SDL_aaevents_c.h new file mode 100644 index 0000000000..6dbc9f691f --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aaevents_c.h @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_aavideo.h" + +/* Variables and functions exported by SDL_sysevents.c to other parts + of the native video subsystem (SDL_sysvideo.c) +*/ +extern void AA_initkeymaps(int fd); +extern void AA_mousecallback(int button, int dx, int dy, + int u1,int u2,int u3, int u4); +extern void AA_keyboardcallback(int scancode, int pressed); + +extern void AA_InitOSKeymap(_THIS); +extern void AA_PumpEvents(_THIS); diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aamouse.c b/apps/plugins/sdl/src/video/aalib/SDL_aamouse.c new file mode 100644 index 0000000000..dc784a56f9 --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aamouse.c @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include + +#include "SDL_mouse.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_aamouse_c.h" + + +/* The implementation dependent data for the window manager cursor */ +struct WMcursor { + int unused; +}; diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aamouse_c.h b/apps/plugins/sdl/src/video/aalib/SDL_aamouse_c.h new file mode 100644 index 0000000000..6ce3d9863b --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aamouse_c.h @@ -0,0 +1,26 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_aavideo.h" + +/* Functions to be exported */ diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aavideo.c b/apps/plugins/sdl/src/video/aalib/SDL_aavideo.c new file mode 100644 index 0000000000..e6d5d3e4ce --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aavideo.c @@ -0,0 +1,388 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* AAlib based SDL video driver implementation. +*/ + +#include +#include + + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_aavideo.h" +#include "SDL_aaevents_c.h" +#include "SDL_aamouse_c.h" + +#include + +/* Initialization/Query functions */ +static int AA_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); +static void AA_VideoQuit(_THIS); + +/* Hardware surface functions */ +static int AA_AllocHWSurface(_THIS, SDL_Surface *surface); +static int AA_LockHWSurface(_THIS, SDL_Surface *surface); +static int AA_FlipHWSurface(_THIS, SDL_Surface *surface); +static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void AA_FreeHWSurface(_THIS, SDL_Surface *surface); + +/* Cache the VideoDevice struct */ +static struct SDL_VideoDevice *local_this; + +/* AAlib driver bootstrap functions */ + +static int AA_Available(void) +{ + return 1; /* Always available ! */ +} + +static void AA_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device->hidden); + SDL_free(device); +} + +static SDL_VideoDevice *AA_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + SDL_memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + SDL_malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + SDL_free(device); + } + return(0); + } + SDL_memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = AA_VideoInit; + device->ListModes = AA_ListModes; + device->SetVideoMode = AA_SetVideoMode; + device->CreateYUVOverlay = NULL; + device->SetColors = AA_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = AA_VideoQuit; + device->AllocHWSurface = AA_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = AA_LockHWSurface; + device->UnlockHWSurface = AA_UnlockHWSurface; + device->FlipHWSurface = NULL; + device->FreeHWSurface = AA_FreeHWSurface; + device->SetCaption = NULL; + device->SetIcon = NULL; + device->IconifyWindow = NULL; + device->GrabInput = NULL; + device->GetWMInfo = NULL; + device->InitOSKeymap = AA_InitOSKeymap; + device->PumpEvents = AA_PumpEvents; + + device->free = AA_DeleteDevice; + + return device; +} + +VideoBootStrap AALIB_bootstrap = { + "aalib", "ASCII Art Library", + AA_Available, AA_CreateDevice +}; + +static void AA_ResizeHandler(aa_context *); + +int AA_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + int keyboard; + int i; + + /* Initialize all variables that we clean on shutdown */ + for ( i=0; ix = SDL_modelist[i]->y = 0; + } + /* Modes sorted largest to smallest */ + SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768; + SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600; + SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480; + SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400; + SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240; + SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200; + SDL_modelist[6] = NULL; + + /* Initialize the library */ + + AA_mutex = SDL_CreateMutex(); + + aa_parseoptions (NULL, NULL, NULL, NULL); + + AA_context = aa_autoinit(&aa_defparams); + if ( ! AA_context ) { + SDL_SetError("Unable to initialize AAlib"); + return(-1); + } + + /* Enable mouse and keyboard support */ + + if ( ! aa_autoinitkbd (AA_context, AA_SENDRELEASE) ) { + SDL_SetError("Unable to initialize AAlib keyboard"); + return(-1); + } + if ( ! aa_autoinitmouse (AA_context, AA_SENDRELEASE) ) { + fprintf(stderr,"Warning: Unable to initialize AAlib mouse"); + } + AA_rparams = aa_getrenderparams(); + + local_this = this; + + aa_resizehandler(AA_context, AA_ResizeHandler); + + fprintf(stderr,"Using AAlib driver: %s (%s)\n", AA_context->driver->name, AA_context->driver->shortname); + + AA_in_x11 = (SDL_strcmp(AA_context->driver->shortname,"X11") == 0); + /* Determine the screen depth (use default 8-bit depth) */ + vformat->BitsPerPixel = 8; + vformat->BytesPerPixel = 1; + + /* We're done! */ + return(0); +} + +SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + if(format->BitsPerPixel != 8) + return NULL; + + if ( flags & SDL_FULLSCREEN ) { + return SDL_modelist; + } else { + return (SDL_Rect **) -1; + } +} + +/* From aavga.c + AAlib does not give us the choice of the actual resolution, thus we have to simulate additional + resolution by scaling down manually each frame +*/ +static void fastscale (register char *b1, register char *b2, int x1, int x2, int y1, int y2) +{ + register int ex, spx = 0, ddx, ddx1; + int ddy1, ddy, spy = 0, ey; + int x; + char *bb1 = b1; + if (!x1 || !x2 || !y1 || !y2) + return; + ddx = x1 + x1; + ddx1 = x2 + x2; + if (ddx1 < ddx) + spx = ddx / ddx1, ddx %= ddx1; + ddy = y1 + y1; + ddy1 = y2 + y2; + if (ddy1 < ddy) + spy = (ddy / ddy1) * x1, ddy %= ddy1; + ey = -ddy1; + for (; y2; y2--) { + ex = -ddx1; + for (x = x2; x; x--) { + *b2 = *b1; + b2++; + b1 += spx; + ex += ddx; + if (ex > 0) { + b1++; + ex -= ddx1; + } + } + bb1 += spy; + ey += ddy; + if (ey > 0) { + bb1 += x1; + ey -= ddy1; + } + b1 = bb1; + } +} + +/* Various screen update functions available */ +static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); + +SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + int mode; + + if ( AA_buffer ) { + SDL_free( AA_buffer ); + } + + AA_buffer = SDL_malloc(width * height); + if ( ! AA_buffer ) { + SDL_SetError("Couldn't allocate buffer for requested mode"); + return(NULL); + } + +/* printf("Setting mode %dx%d\n", width, height); */ + + SDL_memset(aa_image(AA_context), 0, aa_imgwidth(AA_context) * aa_imgheight(AA_context)); + SDL_memset(AA_buffer, 0, width * height); + + /* Allocate the new pixel format for the screen */ + if ( ! SDL_ReallocFormat(current, 8, 0, 0, 0, 0) ) { + return(NULL); + } + + /* Set up the new mode framebuffer */ + current->flags = SDL_FULLSCREEN; + AA_w = current->w = width; + AA_h = current->h = height; + current->pitch = current->w; + current->pixels = AA_buffer; + + AA_x_ratio = ((double)aa_imgwidth(AA_context)) / ((double)width); + AA_y_ratio = ((double)aa_imgheight(AA_context)) / ((double)height); + + /* Set the blit function */ + this->UpdateRects = AA_DirectUpdate; + + /* We're done */ + return(current); +} + +static void AA_ResizeHandler(aa_context *context) +{ + aa_resize(context); + local_this->hidden->x_ratio = ((double)aa_imgwidth(context)) / ((double)local_this->screen->w); + local_this->hidden->y_ratio = ((double)aa_imgheight(context)) / ((double)local_this->screen->h); + + fastscale (local_this->hidden->buffer, aa_image(context), local_this->hidden->w, aa_imgwidth (context), local_this->hidden->h, aa_imgheight (context)); + aa_renderpalette(context, local_this->hidden->palette, local_this->hidden->rparams, 0, 0, aa_scrwidth(context), aa_scrheight(context)); + aa_flush(context); +} + +/* We don't actually allow hardware surfaces other than the main one */ +static int AA_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + return(-1); +} +static void AA_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +/* We need to wait for vertical retrace on page flipped displays */ +static int AA_LockHWSurface(_THIS, SDL_Surface *surface) +{ + /* TODO ? */ + return(0); +} +static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +/* FIXME: How is this done with AAlib? */ +static int AA_FlipHWSurface(_THIS, SDL_Surface *surface) +{ + SDL_mutexP(AA_mutex); + aa_flush(AA_context); + SDL_mutexV(AA_mutex); + return(0); +} + +static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + int i; + SDL_Rect *rect; + + fastscale (AA_buffer, aa_image(AA_context), AA_w, aa_imgwidth (AA_context), AA_h, aa_imgheight (AA_context)); +#if 1 + aa_renderpalette(AA_context, AA_palette, AA_rparams, 0, 0, aa_scrwidth(AA_context), aa_scrheight(AA_context)); +#else + /* Render only the rectangles in the list */ + printf("Update rects : "); + for ( i=0; i < numrects; ++i ) { + rect = &rects[i]; + printf("(%d,%d-%d,%d)", rect->x, rect->y, rect->w, rect->h); + aa_renderpalette(AA_context, AA_palette, AA_rparams, rect->x * AA_x_ratio, rect->y * AA_y_ratio, rect->w * AA_x_ratio, rect->h * AA_y_ratio); + } + printf("\n"); +#endif + SDL_mutexP(AA_mutex); + aa_flush(AA_context); + SDL_mutexV(AA_mutex); + return; +} + +int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + int i; + + for ( i=0; i < ncolors; i++ ) { + aa_setpalette(AA_palette, firstcolor + i, + colors[i].r>>2, + colors[i].g>>2, + colors[i].b>>2); + } + return(1); +} + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +void AA_VideoQuit(_THIS) +{ + int i; + + aa_uninitkbd(AA_context); + aa_uninitmouse(AA_context); + + /* Free video mode lists */ + for ( i=0; iscreen->pixels = NULL; +} diff --git a/apps/plugins/sdl/src/video/aalib/SDL_aavideo.h b/apps/plugins/sdl/src/video/aalib/SDL_aavideo.h new file mode 100644 index 0000000000..987edc9768 --- /dev/null +++ b/apps/plugins/sdl/src/video/aalib/SDL_aavideo.h @@ -0,0 +1,66 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_aavideo_h +#define _SDL_aavideo_h + +#include "SDL_mouse.h" +#include "SDL_mutex.h" +#include "../SDL_sysvideo.h" + +#include + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + +#define SDL_NUMMODES 6 + +/* Private display data */ +struct SDL_PrivateVideoData { + SDL_Rect *SDL_modelist[SDL_NUMMODES+1]; + aa_context *context; + aa_palette palette; + aa_renderparams *rparams; + double x_ratio, y_ratio; + int w, h; + SDL_mutex *mutex; + int in_x11; + void *buffer; +}; + +/* Old variable names */ +#define SDL_modelist (this->hidden->SDL_modelist) +#define AA_context (this->hidden->context) +#define AA_palette (this->hidden->palette) +#define AA_rparams (this->hidden->rparams) +#define AA_buffer (this->hidden->buffer) + +#define AA_x_ratio (this->hidden->x_ratio) +#define AA_y_ratio (this->hidden->y_ratio) + +#define AA_mutex (this->hidden->mutex) +#define AA_in_x11 (this->hidden->in_x11) +#define AA_w (this->hidden->w) +#define AA_h (this->hidden->h) + +#endif /* _SDL_aavideo_h */ diff --git a/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p.S b/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p.S new file mode 100644 index 0000000000..3cd1961b85 --- /dev/null +++ b/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p.S @@ -0,0 +1,452 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* + Chunky to planar conversion routine + 1 byte/pixel -> 4 or 8 bit planes + + Patrice Mandin + Xavier Joubert + Mikael Kalms +*/ + + .globl _SDL_Atari_C2pConvert + .globl _SDL_Atari_C2pConvert8 + .globl _SDL_Atari_C2pConvert4 + .globl _SDL_Atari_C2pConvert4_pal + +/* ------------ Conversion C2P, 8 bits ------------ */ + + .text +_SDL_Atari_C2pConvert8: +#if !defined(__mcoldfire__) + movel sp@(4),c2p_source + movel sp@(8),c2p_dest + movel sp@(12),c2p_width + movel sp@(16),c2p_height + movel sp@(20),c2p_dblligne + movel sp@(24),c2p_srcpitch + movel sp@(28),c2p_dstpitch + + moveml d2-d7/a2-a6,sp@- + + movel c2p_source,c2p_cursrc + movel c2p_dest,c2p_curdst + movel #0x0f0f0f0f,d4 + movel #0x00ff00ff,d5 + movel #0x55555555,d6 + movew c2p_height+2,c2p_row + movew c2p_width+2,d0 + andw #-8,d0 + movew d0,c2p_rowlen + +SDL_Atari_C2p8_rowloop: + + movel c2p_cursrc,a0 + movel c2p_curdst,a1 + + movel a0,a2 + addw c2p_rowlen,a2 + + movel a0@+,d0 + movel a0@+,d1 + movel a0@+,d2 + movel a0@+,d3 +/* + d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0 + d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0 + d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0 + d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0 +*/ + movel d1,d7 + lsrl #4,d7 + eorl d0,d7 + andl d4,d7 + eorl d7,d0 + lsll #4,d7 + eorl d7,d1 + + movel d3,d7 + lsrl #4,d7 + eorl d2,d7 + andl d4,d7 + eorl d7,d2 + lsll #4,d7 + eorl d7,d3 + + movel d2,d7 + lsrl #8,d7 + eorl d0,d7 + andl d5,d7 + eorl d7,d0 + lsll #8,d7 + eorl d7,d2 + + movel d3,d7 + lsrl #8,d7 + eorl d1,d7 + andl d5,d7 + eorl d7,d1 + lsll #8,d7 + eorl d7,d3 +/* + d0 = a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4 + d1 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0 + d2 = b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4 + d3 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0 +*/ + bras SDL_Atari_C2p8_start + +SDL_Atari_C2p8_pix16: + + movel a0@+,d0 + movel a0@+,d1 + movel a0@+,d2 + movel a0@+,d3 +/* + d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0 + d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0 + d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0 + d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0 +*/ + movel d1,d7 + lsrl #4,d7 + movel a3,a1@+ + eorl d0,d7 + andl d4,d7 + eorl d7,d0 + lsll #4,d7 + eorl d7,d1 + + movel d3,d7 + lsrl #4,d7 + eorl d2,d7 + andl d4,d7 + eorl d7,d2 + movel a4,a1@+ + lsll #4,d7 + eorl d7,d3 + + movel d2,d7 + lsrl #8,d7 + eorl d0,d7 + andl d5,d7 + eorl d7,d0 + movel a5,a1@+ + lsll #8,d7 + eorl d7,d2 + + movel d3,d7 + lsrl #8,d7 + eorl d1,d7 + andl d5,d7 + eorl d7,d1 + movel a6,a1@+ + lsll #8,d7 + eorl d7,d3 +/* + d0 = a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4 + d1 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0 + d2 = b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4 + d3 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0 +*/ + +SDL_Atari_C2p8_start: + + movel d2,d7 + lsrl #1,d7 + eorl d0,d7 + andl d6,d7 + eorl d7,d0 + addl d7,d7 + eorl d7,d2 + + movel d3,d7 + lsrl #1,d7 + eorl d1,d7 + andl d6,d7 + eorl d7,d1 + addl d7,d7 + eorl d7,d3 +/* + d0 = a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5 + d1 = a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 + d2 = a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4 + d3 = a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0 +*/ + movew d2,d7 + movew d0,d2 + swap d2 + movew d2,d0 + movew d7,d2 + + movew d3,d7 + movew d1,d3 + swap d3 + movew d3,d1 + movew d7,d3 +/* + d0 = a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4 + d1 = a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 + d2 = c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4 + d3 = c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0 +*/ + movel d2,d7 + lsrl #2,d7 + eorl d0,d7 + andl #0x33333333,d7 + eorl d7,d0 + lsll #2,d7 + eorl d7,d2 + + movel d3,d7 + lsrl #2,d7 + eorl d1,d7 + andl #0x33333333,d7 + eorl d7,d1 + lsll #2,d7 + eorl d7,d3 +/* + d0 = a7b7c7d7e7f7g7h7 i7j7k7l7m7n7o7p7 a6b6c6d6e6f6g6h6 i6j6k6l6m6n6o6p6 + d1 = a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2 + d2 = a5b5c5d5e5f5g5h5 i5j5k5l5m5n5o5p5 a4b4c4d4e4f4g4h4 i4j4k4l4m4n4o4p4 + d3 = a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0 +*/ + swap d0 + swap d1 + swap d2 + swap d3 + + movel d0,a6 + movel d2,a5 + movel d1,a4 + movel d3,a3 + + cmpl a0,a2 + bgt SDL_Atari_C2p8_pix16 + + movel a3,a1@+ + movel a4,a1@+ + movel a5,a1@+ + movel a6,a1@+ + + /* Double the line ? */ + + movel c2p_srcpitch,d0 + movel c2p_dstpitch,d1 + + tstl c2p_dblligne + beqs SDL_Atari_C2p8_nodblline + + movel c2p_curdst,a0 + movel a0,a1 + addl d1,a1 + + movew c2p_width+2,d7 + lsrw #4,d7 + subql #1,d7 +SDL_Atari_C2p8_dblloop: + movel a0@+,a1@+ + movel a0@+,a1@+ + movel a0@+,a1@+ + movel a0@+,a1@+ + dbra d7,SDL_Atari_C2p8_dblloop + + addl d1,c2p_curdst + +SDL_Atari_C2p8_nodblline: + + /* Next line */ + + addl d0,c2p_cursrc + addl d1,c2p_curdst + + subqw #1,c2p_row + bne SDL_Atari_C2p8_rowloop + + moveml sp@+,d2-d7/a2-a6 +#endif + rts + +/* ------------ Conversion C2P, 4 bits ------------ */ + +_SDL_Atari_C2pConvert4: +#if !defined(__mcoldfire__) + movel sp@(4),c2p_source + movel sp@(8),c2p_dest + movel sp@(12),c2p_width + movel sp@(16),c2p_height + movel sp@(20),c2p_dblligne + movel sp@(24),c2p_srcpitch + movel sp@(28),c2p_dstpitch + + moveml d2-d7/a2-a6,sp@- + + movel c2p_source,a0 + movel c2p_dest,a1 + lea _SDL_Atari_table_c2p,a2 + movel #0x00070001,d3 +#if defined(__mc68020__) + moveq #0,d0 +#endif + + movel c2p_height,d7 + subql #1,d7 +c2p4_bcly: + movel a0,a4 | Save start address of source + movel a1,a5 | Save start address of dest + + | Conversion + + movel c2p_width,d6 + lsrw #4,d6 + subql #1,d6 +c2p4_bclx: + | Octets 0-7 + + moveq #0,d1 + moveq #7,d5 +c2p4_bcl07: +#if defined(__mc68020__) + moveb a0@+,d0 + lea a2@(0,d0:w:4),a3 +#else + moveq #0,d0 + moveb a0@+,d0 + lslw #2,d0 + lea a2@(0,d0:w),a3 +#endif + lsll #1,d1 + orl a3@,d1 + dbra d5,c2p4_bcl07 + + movepl d1,a1@(0) + addw d3,a1 + swap d3 + + | Octets 8-15 + + moveq #0,d1 + moveq #7,d5 +c2p4_bcl815: +#if defined(__mc68020__) + moveb a0@+,d0 + lea a2@(0,d0:w:4),a3 +#else + moveq #0,d0 + moveb a0@+,d0 + lslw #2,d0 + lea a2@(0,d0:w),a3 +#endif + lsll #1,d1 + orl a3@,d1 + dbra d5,c2p4_bcl815 + + movepl d1,a1@(0) + addw d3,a1 + swap d3 + + dbra d6,c2p4_bclx + + | Double line ? + + tstl c2p_dblligne + beqs c2p4_nodblligne + + movel a5,a6 | src line + movel a5,a1 | dest line + addl c2p_dstpitch,a1 + + movel c2p_width,d6 + lsrw #3,d6 + subql #1,d6 +c2p4_copydbl: + movel a6@+,a1@+ + dbra d6,c2p4_copydbl + + addl c2p_dstpitch,a5 +c2p4_nodblligne: + + | Next line + + movel a4,a0 + addl c2p_srcpitch,a0 + movel a5,a1 + addl c2p_dstpitch,a1 + + dbra d7,c2p4_bcly + + moveml sp@+,d2-d7/a2-a6 +#endif + rts + +/* ------------ Conversion of a light palette in 4 bits ------------ */ + +_SDL_Atari_C2pConvert4_pal: +#if !defined(__mcoldfire__) + /* a0 is a 256-word light palette */ + movel sp@(4),a0 + + moveml d2-d3,sp@- + + lea _SDL_Atari_table_c2p,a1 + movew #255,d3 +c2p_pal_initbcl: + movew a0@+,d0 + lsrw #4,d0 + andw #15,d0 + + moveq #3,d1 +c2p_pal_initbyte: + btst d1,d0 + sne d2 + negw d2 + moveb d2,a1@(0,d1:w) + + dbra d1,c2p_pal_initbyte + + addql #4,a1 + dbra d3,c2p_pal_initbcl + + moveml sp@+,d2-d3 +#endif + rts + +/* ------------ Buffers ------------ */ + + .bss + + .even + .comm _SDL_Atari_C2pConvert,4 + .comm _SDL_Atari_table_c2p,1024 + + .comm c2p_source,4 /* Source framebuffer */ + .comm c2p_dest,4 /* Destination framebuffer */ + .comm c2p_width,4 /* Width of zone to convert */ + .comm c2p_height,4 /* Height of zone to convert */ + .comm c2p_dblligne,4 /* Double the lines while converting ? */ + .comm c2p_srcpitch,4 /* Source pitch */ + .comm c2p_dstpitch,4 /* Destination pitch */ + .comm c2p_cursrc,4 /* Current source line */ + .comm c2p_curdst,4 /* Current destination line */ + .comm c2p_rowlen,2 /* Line length in bytes */ + .comm c2p_row,2 /* Current line number */ diff --git a/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p_s.h b/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p_s.h new file mode 100644 index 0000000000..48bdae7242 --- /dev/null +++ b/apps/plugins/sdl/src/video/ataricommon/SDL_ataric2p_s.h @@ -0,0 +1,75 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _ATARI_C2P_h +#define _ATARI_C2P_h + +#include "SDL_stdinc.h" + +/*--- Functions pointers ---*/ + +/* Convert a chunky screen to bitplane screen */ + +extern void (*SDL_Atari_C2pConvert)( + Uint8 *src, /* Source screen (one byte=one pixel) */ + Uint8 *dest, /* Destination (4/8 bits planes) */ + Uint32 width, /* Dimensions of screen to convert */ + Uint32 height, + Uint32 dblligne, /* Double the lines when converting ? */ + Uint32 srcpitch, /* Length of one source line in bytes */ + Uint32 dstpitch /* Length of one destination line in bytes */ +); + +/*--- 8 bits functions ---*/ + +/* Convert a chunky screen to bitplane screen */ + +void SDL_Atari_C2pConvert8( + Uint8 *src, /* Source screen (one byte=one pixel) */ + Uint8 *dest, /* Destination (8 bits planes) */ + Uint32 width, /* Dimensions of screen to convert */ + Uint32 height, + Uint32 dblligne, /* Double the lines when converting ? */ + Uint32 srcpitch, /* Length of one source line in bytes */ + Uint32 dstpitch /* Length of one destination line in bytes */ +); + +/*--- 4 bits functions ---*/ + +/* Convert a chunky screen to bitplane screen */ + +void SDL_Atari_C2pConvert4( + Uint8 *src, /* Source screen (one byte=one pixel) */ + Uint8 *dest, /* Destination (4 bits planes) */ + Uint32 width, /* Dimensions of screen to convert */ + Uint32 height, + Uint32 dblligne, /* Double the lines when converting ? */ + Uint32 srcpitch, /* Length of one source line in bytes */ + Uint32 dstpitch /* Length of one destination line in bytes */ +); + +/* Conversion palette */ + +void SDL_Atari_C2pConvert4_pal(Uint16 *lightpalette); + +#endif /* _ATARI_C2P_h */ diff --git a/apps/plugins/sdl/src/video/ataricommon/SDL_ataridevmouse.c b/apps/plugins/sdl/src/video/ataricommon/SDL_ataridevmouse.c new file mode 100644 index 0000000000..0527380bad --- /dev/null +++ b/apps/plugins/sdl/src/video/ataricommon/SDL_ataridevmouse.c @@ -0,0 +1,159 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + MiNT /dev/mouse driver + + Patrice Mandin +*/ + +#include +#include + +#include "../../events/SDL_events_c.h" +#include "SDL_ataridevmouse_c.h" + +/* Defines */ + +#define DEVICE_NAME "/dev/mouse" + +/* Local variables */ + +static int handle = -1; +static int mouseb, prev_mouseb; + +/* Functions */ + +int SDL_AtariDevMouse_Open(void) +{ + int r; + const char *mousedev; + + /* + TODO: Fix the MiNT device driver, that locks mouse for other + applications, so this is disabled till fixed + */ + return 0; + + /* First, try SDL_MOUSEDEV device */ + mousedev = SDL_getenv("SDL_MOUSEDEV"); + if (!mousedev) { + handle = open(mousedev, 0); + } + + /* Failed, try default device */ + if (handle<0) { + handle = open(DEVICE_NAME, 0); + } + + if (handle<0) { + handle = -1; + return 0; + } + + /* Set non blocking mode */ + r = fcntl(handle, F_GETFL, 0); + if (r<0) { + close(handle); + handle = -1; + return 0; + } + + r |= O_NDELAY; + + r = fcntl(handle, F_SETFL, r); + if (r<0) { + close(handle); + handle = -1; + return 0; + } + + prev_mouseb = 7; + return 1; +} + +void SDL_AtariDevMouse_Close(void) +{ + if (handle>0) { + close(handle); + handle = -1; + } +} + +static int atari_GetButton(int button) +{ + switch(button) + { + case 0: + return SDL_BUTTON_RIGHT; + case 1: + return SDL_BUTTON_MIDDLE; + default: + break; + } + + return SDL_BUTTON_LEFT; +} + +void SDL_AtariDevMouse_PostMouseEvents(_THIS, SDL_bool buttonEvents) +{ + unsigned char buffer[3]; + int mousex, mousey; + + if (handle<0) { + return; + } + + mousex = mousey = 0; + while (read(handle, buffer, sizeof(buffer))==sizeof(buffer)) { + mouseb = buffer[0] & 7; + mousex += (char) buffer[1]; + mousey += (char) buffer[2]; + + /* Mouse button events */ + if (buttonEvents && (mouseb != prev_mouseb)) { + int i; + + for (i=0;i<3;i++) { + int curbutton, prevbutton; + + curbutton = mouseb & (1<