[[Mupen64Plus v2.0 Core API v1.0|Mupen64Plus v2.0 API]]

= Mupen64Plus v2.0 Video Extension API =

Most libmupen64plus functions return an <tt>m64p_error</tt> return code, which is an enumerated type defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]].  Plugin code should check the return value of each call to a libmupen64plus function.

All of these functions should only be called from within the video plugin; they should not be called from the front-end.

== Startup/Shutdown Functions ==
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_Init(void)</tt>'''
|-
|Input Parameters
|N/A
|-
|Requirements
|This function should be called before any other Video Extension functions.
|-
|Usage
|This function should be called from within the RomOpen() video plugin function call.  The default SDL implementation of this function simply calls SDL_InitSubSystem(SDL_INIT_VIDEO).  It does not open a rendering window or switch video modes.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_InitWithRenderMode(m64p_render_mode RenderMode)</tt>'''
|-
|Input Parameters
|'''<tt>RenderMode</tt>''' Render mode, either <tt>M64P_RENDER_OPENGL</tt> or <tt>M64P_RENDER_VULKAN</tt>, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]<br />
|-
|Requirements
|This function should be called before any other Video Extension functions.
|-
|Usage
|This function should be called from within the RomOpen() video plugin function call.  The default SDL implementation of this function simply calls SDL_InitSubSystem(SDL_INIT_VIDEO).  It does not open a rendering window or switch video modes.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_Quit(void)</tt>'''
|-
|Input Parameters
|N/A
|-
|Usage
|This function closes any open rendering window and shuts down the video system.  The default SDL implementation of this function calls SDL_QuitSubSystem(SDL_INIT_VIDEO).  This function should be called from within the RomClosed() video plugin function.
|}
<br />

== Screen Handling Functions ==
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_ListFullscreenModes(m64p_2d_size *SizeArray, int *NumSizes)</tt>'''
|-
|Input Parameters
|'''<tt>SizeArray</tt>''' Pointer to an array of <tt>m64p_2d_size</tt> objects, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]<br />
'''<tt>NumSizes</tt>''' Pointer to an integer which contains the size of '''<tt>SizeArray</tt>''' for input, and the number of size objects stored for output.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to enumerate the available resolutions for fullscreen video modes.  An array '''<tt>SizeArray</tt>''' is passed into the function, which is then filled (up to <tt>*'''NumSizes'''</tt> objects) with resolution sizes.  The number of sizes actually written is stored in the integer which is pointed to by '''<tt>NumSizes</tt>'''.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_ListFullscreenRates(m64p_2d_size Size, int *NumRates, int *Rates)</tt>'''
|-
|Input Parameters
|'''<tt>Size</tt>''' <tt>m64p_2d_size</tt> object, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]] of the resolution you want to retrieve the fullscreen refresh rates from.<br />
'''<tt>NumRates</tt>''' Pointer to an integer which contains the size of '''<tt>Rates</tt>''' for input, and the number of size objects stored for output.<br />
'''<tt>Rates</tt>''' Pointer to an array of integers which will contain the refresh rates.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to enumerate the available refresh rates for a given resolution. An '''<tt>m64p_2d_size</tt>''' object is passed into the function, which will contain the resolution of the refresh rates you want to retrieve, an array '''<tt>Rates</tt>''' is passed into the function, which is then filled (up to <tt>*'''NumRates'''</tt> objects) with resolution sizes.  The number of sizes actually written is stored in the integer which is pointed to by '''<tt>NumSizes</tt>'''.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_SetVideoMode(int Width, int Height, int BitsPerPixel, m64p_video_mode ScreenMode, m64p_video_flags Flags)</tt>'''
|-
|Input Parameters
|'''<tt>Width</tt>''' Horizontal resolution in pixels of desired video window<br />
'''<tt>Height</tt>''' Vertical resolution in pixels of desired video window<br />
'''<tt>BitsPerPixel</tt>''' Pixel color resolution of desired video window.  This value must be 16, 24, or 32<br />
'''<tt>ScreenMode</tt>''' Either <tt>M64VIDEO_WINDOWED</tt> or <tt>M64VIDEO_FULLSCREEN</tt><br />
'''<tt>Flags</tt>''' Logical-OR combination of flags which describes the video plugin's capabilities.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function creates a rendering window or switches into a fullscreen video mode.  Any desired OpenGL attributes should be set before calling this function.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_SetVideoModeWithRate(int Width, int Height, int RefreshRate, int BitsPerPixel, m64p_video_mode ScreenMode, m64p_video_flags Flags)</tt>'''
|-
|Input Parameters
|'''<tt>Width</tt>''' Horizontal resolution in pixels of desired video window<br />
'''<tt>Height</tt>''' Vertical resolution in pixels of desired video window<br />
'''<tt>RefreshRate</tt>''' Fullscreen refresh rate<br />
'''<tt>BitsPerPixel</tt>''' Pixel color resolution of desired video window.  This value must be 16, 24, or 32<br />
'''<tt>ScreenMode</tt>''' Either <tt>M64VIDEO_WINDOWED</tt> or <tt>M64VIDEO_FULLSCREEN</tt><br />
'''<tt>Flags</tt>''' Logical-OR combination of flags which describes the video plugin's capabilities.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function creates a rendering window or switches into a fullscreen video mode.  Any desired OpenGL attributes should be set before calling this function.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_SetCaption(const char *Title)</tt>'''
|-
|Input Parameters
|'''<tt>Title</tt>''' Pointer to a NULL-terminated string containing the desired title text of the emulator rendering window
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function sets the caption text of the emulator rendering window.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_ToggleFullScreen(void)</tt>'''
|-
|Input Parameters
|N/A
|-
|Requirements
|The video extension must be initialized before calling this function.  The rendering window should already be created.
|-
|Usage
|This function toggles between fullscreen and windowed rendering modes.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_ResizeWindow(int Width, int Height)</tt>'''
|-
|Input Parameters
|'''<tt>Width</tt>''' Horizontal resolution of resized window in pixels<br />
'''<tt>Height</tt>''' Vertical resolution of resized window in pixels
|-
|Requirements
|The video extension must be initialized before calling this function.  The rendering window should already be created.
|-
|Usage
|This function is called when the video plugin has resized its OpenGL output viewport in response to a ResizeVideoOutput() call, and requests that the window manager update the OpenGL rendering window size to match.  If a front-end application does not support resizable windows and never sets the M64CORE_VIDEO_SIZE core variable with the M64CMD_CORE_STATE_SET command, then this function should not be called.
|}
<br />

===Window Resizing===
The window resizing functionality is particularly complicated, so here is a high-level description of the events which make it happen:

====Without video extension:====
# In VidExt_SetVideoMode(), check if M64VIDEOFLAG_SUPPORT_RESIZING is set
#* if True, create SDL window with RESIZABLE attribute
# Core receives SDL_RESIZE messages in SDL event loop
# If present, Core calls ResizeVideoOutput function in video plugin
# Video Plugin calls ResizeWindow function in Video Extension
#* Core calls SDL_SetVideoMode()
# Core emits M64CORE_VIDEO_SIZE state changed callback

====With video extension:====
# in Front-end SetVideoMode() callback
#* if M64VIDEOFLAG_SUPPORT_RESIZING is set, create resizable window frame
# Front-end GUI gets window resize notification
# Front-end calls CoreDoCommand w/ M64CMD_CORE_STATE_SET, w/ M64CORE_VIDEO_SIZE
# If present, Core calls ResizeVideoOutput function in video plugin
# Video Plugin calls ResizeWindow function in Video Extension
# Core emits M64CORE_VIDEO_SIZE state changed callback

In the Core Video Extension function ResizeWindow, the SDL function SetVideoMode() is called.  This function will destroy the current OpenGL context and create a new one.  For this reason, any video plugin which supports resizable windows must completely reset its OpenGL state including uploading any textures, FBOs, programs, etc after calling the VidExt_ResizeWindow function.

== OpenGL Functions ==
{| border="1"
|Prototype
|'''<tt>void * VidExt_GL_GetProcAddress(const char* Proc)</tt>'''
|-
|Input Parameters
|'''<tt>Proc</tt>''' Pointer to a NULL-terminated string containing the name of the desired OpenGL extension function.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to get a pointer to an OpenGL extension function.  This is only necessary on the Windows platform, because the OpenGL implementation shipped with Windows only supports OpenGL version 1.1.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_GL_SetAttribute(m64p_GLattr Attr, int Value)</tt>'''
|-
|Input Parameters
|'''<tt>Attr</tt>''' Enumerated type (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) specifying which OpenGL attribute to set<br />
'''<tt>Value</tt>''' Value to set for the attribute
|-
|Requirements
|The video extension must be initialized before calling this function.  The desired attributes should be set before calling '''<tt>VidExt_SetVideoMode</tt>'''
|-
|Usage
|This function is used to set certain OpenGL attributes which must be specified before creating the rendering window with '''<tt>VidExt_SetVideoMode</tt>'''.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_GL_GetAttribute(m64p_GLattr Attr, int *pValue)</tt>'''
|-
|Input Parameters
|'''<tt>Attr</tt>''' Enumerated type (defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]) specifying OpenGL attribute of which to get value<br />
'''<tt>pValue</tt>''' Pointer to integer Value which will be set to attribute's value
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function may be used to check that OpenGL attributes where successfully set to the rendering window after the '''<tt>VidExt_SetVideoMode</tt>''' function call.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_GL_SwapBuffers(void)</tt>'''
|-
|Input Parameters
|N/A
|-
|Requirements
|The video extension must be initialized before calling this function.  The rendering window should already be created.
|-
|Usage
|This function is used to swap the front/back buffers after rendering an output video frame.
|}
<br />
{| border="1"
|Prototype
|'''<tt>uint32_t VidExt_GL_GetDefaultFramebuffer(void)</tt>'''
|-
|Input Parameters
|N/A
|-
|Requirements
|The video extension must be initialized before calling this function.  The rendering window should already be created.
|-
|Usage
|On some platforms (for instance, iOS) the default framebuffer object depends on the surface being rendered to, and might be different from 0. This function should be called to retrieve the name of the default FBO. Calling this function may have performance implications and it should not be called every time the default FBO is bound.
|}
<br />

== Vulkan Functions ==
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_VK_GetSurface(void** Surface, void* Instance)</tt>'''
|-
|Input Parameters
|'''<tt>Surface</tt>''' Pointer to a VkSurfaceKHR which will be returned when function succeeds<br />
'''<tt>Instance</tt>''' VkInstance which can be used as the front-end's Vulkan instance
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to retrieve the Vulkan surface
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_VK_GetInstanceExtensions(const char** Extensions[], uint32_t* NumExtensions)</tt>'''
|-
|Input Parameters
|'''<tt>Extensions</tt>''' Pointer to an array of strings<br />
'''<tt>NumExtensions</tt>''' Pointer to an integer which contains the size of the number of objects stored for output.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to retrieve the supported Vulkan extensions.
|}
<br />
