Skip to content

Conversation

enikland3
Copy link

Currently video_manager::frame_update() updates the screen object by calling finish_screen_updates(), that calls screen.update_quads(), where the current m_curbitmap is set as the bitmap to be used by the frame texture. The code then switches the m_curbitmap pointer to the other bitmap available to blit the next frame. The execution returns to after the last call was made in video_manager::frame_update() and continues through the code. One of the remaining calls is machine().osd().update(), where the layout is rendered. If the layout contains a script that calls screen:pixels() to obtain the data of pixels in the frame, it won't get the data of the last frame. To make this work, these changes move switching of screen's current bitmap to after the layout is updated.

@galibert
Copy link
Member

It sounds like a very, very bad idea to call screen:pixels() in a layout in the first place. What do you need that for?

@enikland3
Copy link
Author

Hi OG, thanks for the reply. This is one of three changes I made locally to allow to properly port the hack that displays Sega Master System 3D games without flicker from the driver code to a layout script. The hack is a nice workaround that allows to play 3D games without headache or vision impairment and allows to use a modern 3D display (or glasses) that converts side-by-side image into 3D, as a user have already take advantage of that.

Natively the game displays the image intended for the left eye while controls the shutter glasses to block the right eye's view, then displays the right-eye image while blocks the left eye, in a cycle that keeps repeating while the game is running. This is simulated in MAME using a layout that has at least two views: a view for the standard TV screen and a view for the 3D glasses, that displays two images side-by-side, for each lenses, but because the game only displays the image for the opened lenses each time, it is displayed at a side and the other side shows a black color.

The current implementation of the hack in the driver uses 2 additional screens (left_lcd and right_lcd) that are used for each side of the layout view for the 3D glasses. When an image is drawn at a screen, a temporary bitmap keeps it and draws it again at the same screen in the next frame, when the game draws the other screen. The result is a simultaneous display of the images for the two lenses, why I called it the binocular hack. The hack works very well, but @happppp says it is very wrong and it was already questioned by a user (issue #11279 - deleted - subject:"[sms1pal] wrongly reports 3 screens in -listxml"). They have a good reason: it does not documents the hardware properly, one of the main goals of MAME. Moving the hack to the layout script would solve this problem.

The layout script version of the hack makes use of the screen:pixels() function to copy the frame to a bitmap, the element:invalidate() and element:set_draw_callback() functions to create a custom callback to drawn the rectange that would occlude the side of the blocked view, and the bitmap:resample() function to drawn the copied frame into that rectangle.

This change alone is not enough to move the hack to a layout script. I also need a solution for issue #14142 and I have one more change waiting that implements a function in luaengine_render.cpp to draw the output of screen:pixels() to a bitmap much faster than doing in pure Lua code. Performance is still halved when compared to the hack in the driver but framerate is still hundreds of FPS with modern PCs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants