diff options
Diffstat (limited to 'src/osd/modules/render/drawsdl.cpp')
-rw-r--r-- | src/osd/modules/render/drawsdl.cpp | 235 |
1 files changed, 234 insertions, 1 deletions
diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp index b9a40038082..221ac79ef4d 100644 --- a/src/osd/modules/render/drawsdl.cpp +++ b/src/osd/modules/render/drawsdl.cpp @@ -40,9 +40,11 @@ struct sdl_scale_mode; +#if (SDLMAME_SDL2) #define DRAW2_SCALEMODE_NEAREST "0" #define DRAW2_SCALEMODE_LINEAR "1" #define DRAW2_SCALEMODE_BEST "2" +#endif /* sdl_info is the information about SDL for the current screen */ class sdl_info : public osd_renderer @@ -51,8 +53,12 @@ public: sdl_info(osd_window *w, int extra_flags) : osd_renderer(w, extra_flags), + #if (SDLMAME_SDL2) m_sdl_renderer(NULL), m_texture_id(NULL), + #else + m_yuvsurf(NULL), + #endif m_yuv_lookup(NULL), m_yuv_bitmap(NULL), //m_hw_scale_width(0), @@ -82,14 +88,24 @@ public: private: void destroy_all_textures(); void yuv_init(); +#if (SDLMAME_SDL2) void setup_texture(const osd_dim &size); +#endif void yuv_lookup_set(unsigned int pen, unsigned char red, unsigned char green, unsigned char blue); +#if (!SDLMAME_SDL2) + void yuv_overlay_init(); +#endif + INT32 m_blittimer; +#if (SDLMAME_SDL2) SDL_Renderer *m_sdl_renderer; SDL_Texture *m_texture_id; +#else + SDL_Overlay *m_yuvsurf; +#endif // YUV overlay UINT32 *m_yuv_lookup; @@ -111,7 +127,11 @@ struct sdl_scale_mode int is_yuv; /* Yuv mode? */ int mult_w; /* Width multiplier */ int mult_h; /* Height multiplier */ +#if (!SDLMAME_SDL2) + int m_extra_flags; /* Texture/surface flags */ +#else const char *sdl_scale_mode_hint; /* what to use as a hint ? */ +#endif int pixel_format; /* Pixel/Overlay format */ void (*yuv_blit)(const UINT16 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height); }; @@ -140,6 +160,20 @@ static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, // Static declarations +#if (!SDLMAME_SDL2) +static int shown_video_info = 0; + +static const sdl_scale_mode scale_modes[] = +{ + { "none", 0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF, 0, 0 }, + { "async", 0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF | osd_renderer::FLAG_NEEDS_ASYNCBLIT, 0, 0 }, + { "yv12", 1, 1, 1, 1, 0, SDL_YV12_OVERLAY, yuv_RGB_to_YV12 }, + { "yv12x2", 1, 1, 2, 2, 0, SDL_YV12_OVERLAY, yuv_RGB_to_YV12X2 }, + { "yuy2", 1, 1, 1, 1, 0, SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2 }, + { "yuy2x2", 1, 1, 2, 1, 0, SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2X2 }, + { NULL } +}; +#else static const sdl_scale_mode scale_modes[] = { { "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, 0 }, @@ -152,6 +186,7 @@ static const sdl_scale_mode scale_modes[] = { "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 }, { NULL } }; +#endif //============================================================ // drawsdl_scale_mode @@ -191,7 +226,12 @@ int drawsdl_scale_mode(const char *s) static osd_renderer *drawsdl_create(osd_window *window) { // FIXME: QUALITY HINTS +#if (SDLMAME_SDL2) return global_alloc(sdl_info(window, osd_renderer::FLAG_NONE)); +#else + const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode]; + return global_alloc(sdl_info(window, sm->m_extra_flags)); +#endif } //============================================================ @@ -204,7 +244,11 @@ int drawsdl_init(osd_draw_callbacks *callbacks) callbacks->create = drawsdl_create; callbacks->exit = drawsdl_exit; - osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n"); + if (SDLMAME_SDL2) + osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n"); + else + osd_printf_verbose("Using SDL single-window soft driver (SDL 1.2)\n"); + return 0; } @@ -220,6 +264,7 @@ static void drawsdl_exit(void) // setup_texture for window //============================================================ +#if (SDLMAME_SDL2) void sdl_info::setup_texture(const osd_dim &size) { const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode]; @@ -266,11 +311,64 @@ void sdl_info::setup_texture(const osd_dim &size) size.width(), size.height()); } } +#endif + +//============================================================ +// yuv_overlay_init +//============================================================ + +#if (!SDLMAME_SDL2) +void sdl_info::yuv_overlay_init() +{ + const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode]; + int minimum_width, minimum_height; + + window().target()->compute_minimum_size(minimum_width, minimum_height); + + if (window().prescale()) + { + minimum_width *= window().prescale(); + minimum_height *= window().prescale(); + } + + if (m_yuvsurf != NULL) + { + SDL_FreeYUVOverlay(m_yuvsurf); + m_yuvsurf = NULL; + } + + if (m_yuv_bitmap != NULL) + { + global_free_array(m_yuv_bitmap); + } + + osd_printf_verbose("SDL: Creating %d x %d YUV-Overlay ...\n", minimum_width, minimum_height); + + m_yuv_bitmap = global_alloc_array(UINT16, minimum_width*minimum_height); + + m_yuvsurf = SDL_CreateYUVOverlay(minimum_width * sdl_sm->mult_w, minimum_height * sdl_sm->mult_h, + sdl_sm->pixel_format, window().sdl_surface()); + + if ( m_yuvsurf == NULL ) { + osd_printf_error("SDL: Couldn't create SDL_yuv_overlay: %s\n", SDL_GetError()); + //return 1; + } + + if (!shown_video_info) + { + osd_printf_verbose("YUV Mode : %s\n", sdl_sm->name); + osd_printf_verbose("YUV Overlay Size : %d x %d\n", minimum_width, minimum_height); + osd_printf_verbose("YUV Acceleration : %s\n", m_yuvsurf->hw_overlay ? "Hardware" : "Software"); + shown_video_info = 1; + } +} +#endif //============================================================ // drawsdl_show_info //============================================================ +#if (SDLMAME_SDL2) static void drawsdl_show_info(struct SDL_RendererInfo *render_info) { #define RF_ENTRY(x) {x, #x } @@ -297,14 +395,42 @@ static void drawsdl_show_info(struct SDL_RendererInfo *render_info) if (render_info->flags & rflist[i].flag) osd_printf_verbose("renderer: flag %s\n", rflist[i].name); } +#endif //============================================================ // sdl_info::create +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a +// a //============================================================ int sdl_info::create() { +#if (SDLMAME_SDL2) const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode]; // create renderer @@ -360,6 +486,8 @@ int sdl_info::create() window().get_size(w, h); setup_texture(w, h); #endif +#else +#endif m_yuv_lookup = NULL; m_blittimer = 0; @@ -389,7 +517,9 @@ void sdl_info::destroy() global_free_array(m_yuv_bitmap); m_yuv_bitmap = NULL; } +#if (SDLMAME_SDL2) SDL_DestroyRenderer(m_sdl_renderer); +#endif } //============================================================ @@ -413,8 +543,16 @@ int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt) void sdl_info::destroy_all_textures() { +#if (SDLMAME_SDL2) SDL_DestroyTexture(m_texture_id); m_texture_id = NULL; +#else + if (m_yuvsurf != NULL) + { + SDL_FreeYUVOverlay(m_yuvsurf); + m_yuvsurf = NULL; + } +#endif } @@ -428,7 +566,9 @@ int sdl_info::draw(int update) UINT8 *surfptr; INT32 pitch; Uint32 rmask, gmask, bmask; +#if (SDLMAME_SDL2) Uint32 amask; +#endif INT32 vofs, hofs, blitwidth, blitheight, ch, cw; int bpp; @@ -444,14 +584,68 @@ int sdl_info::draw(int update) clear_flags(FI_CHANGED); m_blittimer = 3; m_last_dim = wdim; +#if (SDLMAME_SDL2) SDL_RenderSetViewport(m_sdl_renderer, NULL); if (m_texture_id != NULL) SDL_DestroyTexture(m_texture_id); setup_texture(m_blit_dim); m_blittimer = 3; +#else + const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode]; + if (sdl_sm->is_yuv) + { + yuv_overlay_init(); + } +#endif } // lock it if we need it +#if (!SDLMAME_SDL2) + + pitch = window().sdl_surface()->pitch; + bpp = window().sdl_surface()->format->BytesPerPixel; + rmask = window().sdl_surface()->format->Rmask; + gmask = window().sdl_surface()->format->Gmask; + bmask = window().sdl_surface()->format->Bmask; +// amask = sdlsurf->format->Amask; +#if 0 + if (window().blitwidth() != m_old_blitwidth || window().blitheight() != m_old_blitheight) + { + if (sm->is_yuv) + yuv_overlay_init(); + m_old_blitwidth = window().blitwidth(); + m_old_blitheight = window().blitheight(); + m_blittimer = 3; + } +#endif + if (SDL_MUSTLOCK(window().sdl_surface())) + SDL_LockSurface(window().sdl_surface()); + + // Clear if necessary + if (m_blittimer > 0) + { + memset(window().sdl_surface()->pixels, 0, wdim.height() * window().sdl_surface()->pitch); + m_blittimer--; + } + + + if (sm->is_yuv) + { + SDL_LockYUVOverlay(m_yuvsurf); + surfptr = m_yuvsurf->pixels[0]; // (UINT8 *) m_yuv_bitmap; + pitch = m_yuvsurf->pitches[0]; // (UINT8 *) m_yuv_bitmap; +#if 0 + printf("abcd %d\n", m_yuvsurf->h); + printf("abcd %d %d %d\n", m_yuvsurf->pitches[0], m_yuvsurf->pitches[1], m_yuvsurf->pitches[2]); + printf("abcd %p %p %p\n", m_yuvsurf->pixels[0], m_yuvsurf->pixels[1], m_yuvsurf->pixels[2]); + printf("abcd %ld %ld\n", m_yuvsurf->pixels[1] - m_yuvsurf->pixels[0], m_yuvsurf->pixels[2] - m_yuvsurf->pixels[1]); +#endif + } + else + surfptr = (UINT8 *)window().sdl_surface()->pixels; +#else + //SDL_SelectRenderer(window().sdl_window); + { Uint32 format; @@ -474,6 +668,7 @@ int sdl_info::draw(int update) SDL_LockTexture(m_texture_id, NULL, (void **) &surfptr, &pitch); +#endif // get ready to center the image vofs = hofs = 0; blitwidth = m_blit_dim.width(); @@ -508,11 +703,25 @@ int sdl_info::draw(int update) int mamewidth, mameheight; +#if !SDLMAME_SDL2 + if (!sm->is_yuv) + { + surfptr += ((vofs * pitch) + (hofs * bpp)); + mamewidth = blitwidth; //sdl_surface()->w; + mameheight = blitheight; //sdl_surface()->h; + } + else + { + mamewidth = m_yuvsurf->w / sm->mult_w; + mameheight = m_yuvsurf->h / sm->mult_h; + } +#else Uint32 fmt = 0; int access = 0; SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight); mamewidth /= sm->mult_w; mameheight /= sm->mult_h; +#endif //printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight); // rescale bounds @@ -571,6 +780,24 @@ int sdl_info::draw(int update) window().m_primlist->release_lock(); // unlock and flip +#if (!SDLMAME_SDL2) + if (SDL_MUSTLOCK(window().sdl_surface())) SDL_UnlockSurface(window().sdl_surface()); + if (!sm->is_yuv) + { + SDL_Flip(window().sdl_surface()); + } + else + { + SDL_Rect r; + + SDL_UnlockYUVOverlay(m_yuvsurf); + r.x = hofs; + r.y = vofs; + r.w = blitwidth; + r.h = blitheight; + SDL_DisplayYUVOverlay(m_yuvsurf, &r); + } +#else SDL_UnlockTexture(m_texture_id); { SDL_Rect r; @@ -584,6 +811,7 @@ int sdl_info::draw(int update) SDL_RenderCopy(m_sdl_renderer,m_texture_id, NULL, &r); SDL_RenderPresent(m_sdl_renderer); } +#endif return 0; } //============================================================ @@ -722,7 +950,12 @@ static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, pixels[0] = ptr; pixels[1] = ptr + pitch * height * 2; +#if (SDLMAME_SDL2) int p2 = (pitch >> 1); +#else + int p2 = (pitch + 7) & ~ 7;; + p2 = (p2 >> 1); +#endif pixels[2] = pixels[1] + p2 * height; for(y=0;y<height;y++) |