2020-10-12 23:34:22 +08:00
// dear imgui: Renderer + Platform Backend for Marmalade + IwGx
2018-09-13 22:44:08 +08:00
// Marmalade code: Copyright (C) 2015 by Giovanni Zito (this file is part of Dear ImGui)
2018-02-06 03:34:11 +08:00
// Implemented features:
2019-10-16 17:23:15 +08:00
// [X] Renderer: User texture binding. Use 'CIwTexture*' as ImTextureID. Read the FAQ about ImTextureID!
2019-02-12 01:38:07 +08:00
// Missing features:
// [ ] Renderer: Clipping rectangles are not honored.
2016-03-24 18:00:47 +08:00
2021-05-27 19:59:35 +08:00
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
2020-10-14 18:22:53 +08:00
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
2015-10-09 04:38:37 +08:00
2018-02-17 02:18:16 +08:00
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
2021-02-07 19:36:54 +08:00
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
2019-07-22 09:39:50 +08:00
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
2019-05-11 16:33:56 +08:00
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
2018-12-01 01:18:15 +08:00
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
2018-02-17 02:18:16 +08:00
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_Marmalade_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
2018-01-29 21:38:46 +08:00
# include "imgui.h"
2015-10-09 04:38:37 +08:00
# include "imgui_impl_marmalade.h"
# include <s3eClipboard.h>
2016-03-26 22:43:45 +08:00
# include <s3ePointer.h>
2015-10-09 04:38:37 +08:00
# include <s3eKeyboard.h>
# include <IwTexture.h>
# include <IwGx.h>
// Data
static double g_Time = 0.0f ;
static bool g_MousePressed [ 3 ] = { false , false , false } ;
2015-10-15 18:44:30 +08:00
static CIwTexture * g_FontTexture = NULL ;
static char * g_ClipboardText = NULL ;
static bool g_osdKeyboardEnabled = false ;
2015-10-15 05:01:52 +08:00
// use this setting to scale the interface - e.g. on device you could use 2 or 3 scale factor
2020-06-30 21:31:54 +08:00
static ImVec2 g_RenderScale = ImVec2 ( 1.0f , 1.0f ) ;
2015-10-09 04:38:37 +08:00
2018-02-17 02:18:16 +08:00
// Render function.
void ImGui_Marmalade_RenderDrawData ( ImDrawData * draw_data )
2015-10-09 04:38:37 +08:00
{
2019-04-16 00:47:36 +08:00
// Avoid rendering when minimized
if ( draw_data - > DisplaySize . x < = 0.0f | | draw_data - > DisplaySize . y < = 0.0f )
return ;
2015-10-15 05:01:52 +08:00
// Render command lists
2018-12-01 01:18:15 +08:00
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
2015-10-15 05:01:52 +08:00
{
const ImDrawList * cmd_list = draw_data - > CmdLists [ n ] ;
2016-09-04 01:24:57 +08:00
const ImDrawIdx * idx_buffer = cmd_list - > IdxBuffer . Data ;
const int nVert = cmd_list - > VtxBuffer . Size ;
2015-10-15 18:44:30 +08:00
CIwFVec2 * pVertStream = IW_GX_ALLOC ( CIwFVec2 , nVert ) ;
CIwFVec2 * pUVStream = IW_GX_ALLOC ( CIwFVec2 , nVert ) ;
CIwColour * pColStream = IW_GX_ALLOC ( CIwColour , nVert ) ;
2018-12-01 01:18:15 +08:00
for ( int i = 0 ; i < nVert ; i + + )
2015-10-15 18:44:30 +08:00
{
2019-02-12 01:38:07 +08:00
// FIXME-OPT: optimize multiplication on GPU using vertex shader/projection matrix.
Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more)
2017-11-01 21:24:09 +08:00
pVertStream [ i ] . x = cmd_list - > VtxBuffer [ i ] . pos . x * g_RenderScale . x ;
pVertStream [ i ] . y = cmd_list - > VtxBuffer [ i ] . pos . y * g_RenderScale . y ;
2015-10-15 18:44:30 +08:00
pUVStream [ i ] . x = cmd_list - > VtxBuffer [ i ] . uv . x ;
pUVStream [ i ] . y = cmd_list - > VtxBuffer [ i ] . uv . y ;
pColStream [ i ] = cmd_list - > VtxBuffer [ i ] . col ;
2015-10-15 05:01:52 +08:00
}
2015-10-15 18:44:30 +08:00
IwGxSetVertStreamScreenSpace ( pVertStream , nVert ) ;
IwGxSetUVStream ( pUVStream ) ;
IwGxSetColStream ( pColStream , nVert ) ;
IwGxSetNormStream ( 0 ) ;
2015-10-15 05:01:52 +08:00
2016-09-04 01:24:57 +08:00
for ( int cmd_i = 0 ; cmd_i < cmd_list - > CmdBuffer . Size ; cmd_i + + )
2015-10-15 05:01:52 +08:00
{
const ImDrawCmd * pcmd = & cmd_list - > CmdBuffer [ cmd_i ] ;
2015-10-15 18:44:30 +08:00
if ( pcmd - > UserCallback )
2015-10-15 05:01:52 +08:00
{
2016-09-04 01:24:57 +08:00
pcmd - > UserCallback ( cmd_list , pcmd ) ;
2015-10-15 05:01:52 +08:00
}
else
{
2019-02-12 01:38:07 +08:00
// FIXME: Not honoring ClipRect fields.
2015-10-15 18:44:30 +08:00
CIwMaterial * pCurrentMaterial = IW_GX_ALLOC_MATERIAL ( ) ;
pCurrentMaterial - > SetShadeMode ( CIwMaterial : : SHADE_FLAT ) ;
pCurrentMaterial - > SetCullMode ( CIwMaterial : : CULL_NONE ) ;
pCurrentMaterial - > SetFiltering ( false ) ;
pCurrentMaterial - > SetAlphaMode ( CIwMaterial : : ALPHA_BLEND ) ;
2015-10-15 05:01:52 +08:00
pCurrentMaterial - > SetDepthWriteMode ( CIwMaterial : : DEPTH_WRITE_NORMAL ) ;
pCurrentMaterial - > SetAlphaTestMode ( CIwMaterial : : ALPHATEST_DISABLED ) ;
2021-02-07 19:36:54 +08:00
pCurrentMaterial - > SetTexture ( ( CIwTexture * ) pcmd - > GetTexID ( ) ) ;
2015-10-15 18:44:30 +08:00
IwGxSetMaterial ( pCurrentMaterial ) ;
IwGxDrawPrims ( IW_GX_TRI_LIST , ( uint16 * ) idx_buffer , pcmd - > ElemCount ) ;
2015-10-15 05:01:52 +08:00
}
idx_buffer + = pcmd - > ElemCount ;
}
2015-10-15 18:44:30 +08:00
IwGxFlush ( ) ;
2015-10-15 05:01:52 +08:00
}
2015-10-15 18:44:30 +08:00
// TODO: restore modified state (i.e. mvp matrix)
2015-10-09 04:38:37 +08:00
}
2016-10-15 17:36:43 +08:00
static const char * ImGui_Marmalade_GetClipboardText ( void * /*user_data*/ )
2015-10-09 04:38:37 +08:00
{
2016-10-15 17:36:43 +08:00
if ( ! s3eClipboardAvailable ( ) )
return NULL ;
if ( int size = s3eClipboardGetText ( NULL , 0 ) )
2015-10-15 18:44:30 +08:00
{
2016-10-15 17:36:43 +08:00
if ( g_ClipboardText )
delete [ ] g_ClipboardText ;
g_ClipboardText = new char [ size ] ;
g_ClipboardText [ 0 ] = ' \0 ' ;
s3eClipboardGetText ( g_ClipboardText , size ) ;
2015-10-15 05:01:52 +08:00
}
2015-10-15 18:44:30 +08:00
return g_ClipboardText ;
2015-10-09 04:38:37 +08:00
}
2016-10-15 17:36:43 +08:00
static void ImGui_Marmalade_SetClipboardText ( void * /*user_data*/ , const char * text )
2015-10-09 04:38:37 +08:00
{
2015-10-15 18:44:30 +08:00
if ( s3eClipboardAvailable ( ) )
2015-10-15 05:01:52 +08:00
s3eClipboardSetText ( text ) ;
2015-10-09 04:38:37 +08:00
}
2018-06-21 18:04:00 +08:00
int32 ImGui_Marmalade_PointerButtonEventCallback ( void * system_data , void * user_data )
2015-10-09 04:38:37 +08:00
{
2015-10-15 05:01:52 +08:00
// pEvent->m_Button is of type s3ePointerButton and indicates which mouse
2015-10-15 18:44:30 +08:00
// button was pressed. For touchscreen this should always have the value
2015-10-15 05:01:52 +08:00
// S3E_POINTER_BUTTON_SELECT
2018-06-21 18:04:00 +08:00
s3ePointerEvent * pEvent = ( s3ePointerEvent * ) system_data ;
2015-10-15 05:01:52 +08:00
2016-03-26 22:43:45 +08:00
if ( pEvent - > m_Pressed = = 1 )
2015-10-15 18:44:30 +08:00
{
if ( pEvent - > m_Button = = S3E_POINTER_BUTTON_LEFTMOUSE )
2015-10-15 05:01:52 +08:00
g_MousePressed [ 0 ] = true ;
2015-10-15 18:44:30 +08:00
if ( pEvent - > m_Button = = S3E_POINTER_BUTTON_RIGHTMOUSE )
2015-10-15 05:01:52 +08:00
g_MousePressed [ 1 ] = true ;
2015-10-15 18:44:30 +08:00
if ( pEvent - > m_Button = = S3E_POINTER_BUTTON_MIDDLEMOUSE )
2015-10-15 05:01:52 +08:00
g_MousePressed [ 2 ] = true ;
2015-10-15 18:44:30 +08:00
if ( pEvent - > m_Button = = S3E_POINTER_BUTTON_MOUSEWHEELUP )
2018-01-20 19:45:31 +08:00
io . MouseWheel + = pEvent - > m_y ;
2015-10-15 18:44:30 +08:00
if ( pEvent - > m_Button = = S3E_POINTER_BUTTON_MOUSEWHEELDOWN )
2018-01-20 19:45:31 +08:00
io . MouseWheel + = pEvent - > m_y ;
2015-10-15 05:01:52 +08:00
}
return 0 ;
2015-10-09 04:38:37 +08:00
}
2018-06-21 18:04:00 +08:00
int32 ImGui_Marmalade_KeyCallback ( void * system_data , void * user_data )
2015-10-09 04:38:37 +08:00
{
2015-10-15 05:01:52 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-06-21 18:04:00 +08:00
s3eKeyboardEvent * e = ( s3eKeyboardEvent * ) system_data ;
2015-10-15 18:44:30 +08:00
if ( e - > m_Pressed = = 1 )
2015-10-15 05:01:52 +08:00
io . KeysDown [ e - > m_Key ] = true ;
2015-10-15 18:44:30 +08:00
if ( e - > m_Pressed = = 0 )
2015-10-15 05:01:52 +08:00
io . KeysDown [ e - > m_Key ] = false ;
2016-03-26 22:43:45 +08:00
2015-10-15 18:44:30 +08:00
io . KeyCtrl = s3eKeyboardGetState ( s3eKeyLeftControl ) = = S3E_KEY_STATE_DOWN | | s3eKeyboardGetState ( s3eKeyRightControl ) = = S3E_KEY_STATE_DOWN ;
io . KeyShift = s3eKeyboardGetState ( s3eKeyLeftShift ) = = S3E_KEY_STATE_DOWN | | s3eKeyboardGetState ( s3eKeyRightShift ) = = S3E_KEY_STATE_DOWN ;
io . KeyAlt = s3eKeyboardGetState ( s3eKeyLeftAlt ) = = S3E_KEY_STATE_DOWN | | s3eKeyboardGetState ( s3eKeyRightAlt ) = = S3E_KEY_STATE_DOWN ;
2016-04-03 00:22:40 +08:00
io . KeySuper = s3eKeyboardGetState ( s3eKeyLeftWindows ) = = S3E_KEY_STATE_DOWN | | s3eKeyboardGetState ( s3eKeyRightWindows ) = = S3E_KEY_STATE_DOWN ;
2015-10-15 05:01:52 +08:00
2015-10-15 18:44:30 +08:00
return 0 ;
2015-10-09 04:38:37 +08:00
}
2018-06-21 18:04:00 +08:00
int32 ImGui_Marmalade_CharCallback ( void * system_data , void * user_data )
2015-10-09 04:38:37 +08:00
{
2015-10-15 05:01:52 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-06-21 18:04:00 +08:00
s3eKeyboardCharEvent * e = ( s3eKeyboardCharEvent * ) system_data ;
2019-05-11 16:33:56 +08:00
io . AddInputCharacter ( ( unsigned int ) e - > m_Char ) ;
2015-10-09 04:38:37 +08:00
2015-10-15 18:44:30 +08:00
return 0 ;
2015-10-09 04:38:37 +08:00
}
bool ImGui_Marmalade_CreateDeviceObjects ( )
{
// Build texture atlas
2015-11-29 22:54:05 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2015-10-09 04:38:37 +08:00
unsigned char * pixels ;
int width , height ;
io . Fonts - > GetTexDataAsRGBA32 ( & pixels , & width , & height ) ;
2015-11-29 22:54:05 +08:00
// Upload texture to graphics system
2015-10-15 18:44:30 +08:00
g_FontTexture = new CIwTexture ( ) ;
g_FontTexture - > SetModifiable ( true ) ;
CIwImage & image = g_FontTexture - > GetImage ( ) ;
image . SetFormat ( CIwImage : : ARGB_8888 ) ;
image . SetWidth ( width ) ;
image . SetHeight ( height ) ;
2015-10-15 05:01:52 +08:00
image . SetBuffers ( ) ; // allocates and own buffers
2015-10-15 18:44:30 +08:00
image . ReadTexels ( pixels ) ;
g_FontTexture - > SetMipMapping ( false ) ;
g_FontTexture - > SetFiltering ( false ) ;
g_FontTexture - > Upload ( ) ;
2015-10-09 04:38:37 +08:00
2015-11-29 22:54:05 +08:00
// Store our identifier
2021-02-04 01:30:26 +08:00
io . Fonts - > SetTexID ( ( ImTextureID ) g_FontTexture ) ;
2015-10-09 04:38:37 +08:00
return true ;
}
void ImGui_Marmalade_InvalidateDeviceObjects ( )
{
2016-03-26 22:43:45 +08:00
if ( g_ClipboardText )
2015-10-15 18:44:30 +08:00
{
delete [ ] g_ClipboardText ;
g_ClipboardText = NULL ;
2015-10-15 05:01:52 +08:00
}
2015-10-09 04:38:37 +08:00
if ( g_FontTexture )
{
2021-02-04 01:30:26 +08:00
ImGui : : GetIO ( ) . Fonts - > SetTexID ( 0 ) ;
2015-10-15 18:44:30 +08:00
delete g_FontTexture ;
g_FontTexture = NULL ;
2015-10-09 04:38:37 +08:00
}
}
2015-10-15 18:44:30 +08:00
bool ImGui_Marmalade_Init ( bool install_callbacks )
2015-10-09 04:38:37 +08:00
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-12-01 01:18:15 +08:00
io . BackendPlatformName = io . BackendRendererName = " imgui_impl_marmalade " ;
2021-03-04 18:03:40 +08:00
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
io . KeyMap [ ImGuiKey_Tab ] = s3eKeyTab
2015-10-09 04:38:37 +08:00
io . KeyMap [ ImGuiKey_LeftArrow ] = s3eKeyLeft ;
io . KeyMap [ ImGuiKey_RightArrow ] = s3eKeyRight ;
io . KeyMap [ ImGuiKey_UpArrow ] = s3eKeyUp ;
io . KeyMap [ ImGuiKey_DownArrow ] = s3eKeyDown ;
io . KeyMap [ ImGuiKey_PageUp ] = s3eKeyPageUp ;
io . KeyMap [ ImGuiKey_PageDown ] = s3eKeyPageDown ;
io . KeyMap [ ImGuiKey_Home ] = s3eKeyHome ;
io . KeyMap [ ImGuiKey_End ] = s3eKeyEnd ;
2018-01-08 22:30:39 +08:00
io . KeyMap [ ImGuiKey_Insert ] = s3eKeyInsert ;
2015-10-09 04:38:37 +08:00
io . KeyMap [ ImGuiKey_Delete ] = s3eKeyDelete ;
io . KeyMap [ ImGuiKey_Backspace ] = s3eKeyBackspace ;
2018-02-07 02:29:31 +08:00
io . KeyMap [ ImGuiKey_Space ] = s3eKeySpace ;
2015-10-09 04:38:37 +08:00
io . KeyMap [ ImGuiKey_Enter ] = s3eKeyEnter ;
io . KeyMap [ ImGuiKey_Escape ] = s3eKeyEsc ;
2019-07-22 09:39:50 +08:00
io . KeyMap [ ImGuiKey_KeyPadEnter ] = s3eKeyNumPadEnter ;
2015-10-09 04:38:37 +08:00
io . KeyMap [ ImGuiKey_A ] = s3eKeyA ;
io . KeyMap [ ImGuiKey_C ] = s3eKeyC ;
io . KeyMap [ ImGuiKey_V ] = s3eKeyV ;
io . KeyMap [ ImGuiKey_X ] = s3eKeyX ;
io . KeyMap [ ImGuiKey_Y ] = s3eKeyY ;
io . KeyMap [ ImGuiKey_Z ] = s3eKeyZ ;
io . SetClipboardTextFn = ImGui_Marmalade_SetClipboardText ;
io . GetClipboardTextFn = ImGui_Marmalade_GetClipboardText ;
if ( install_callbacks )
{
2015-10-15 18:44:30 +08:00
s3ePointerRegister ( S3E_POINTER_BUTTON_EVENT , ImGui_Marmalade_PointerButtonEventCallback , 0 ) ;
s3eKeyboardRegister ( S3E_KEYBOARD_KEY_EVENT , ImGui_Marmalade_KeyCallback , 0 ) ;
s3eKeyboardRegister ( S3E_KEYBOARD_CHAR_EVENT , ImGui_Marmalade_CharCallback , 0 ) ;
2015-10-15 05:01:52 +08:00
}
2015-10-09 04:38:37 +08:00
return true ;
}
void ImGui_Marmalade_Shutdown ( )
{
ImGui_Marmalade_InvalidateDeviceObjects ( ) ;
}
void ImGui_Marmalade_NewFrame ( )
{
2015-10-15 18:44:30 +08:00
if ( ! g_FontTexture )
2015-10-09 04:38:37 +08:00
ImGui_Marmalade_CreateDeviceObjects ( ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
// Setup display size (every frame to accommodate for window resizing)
2015-10-15 18:44:30 +08:00
int w = IwGxGetScreenWidth ( ) , h = IwGxGetScreenHeight ( ) ;
2015-10-09 04:38:37 +08:00
io . DisplaySize = ImVec2 ( ( float ) w , ( float ) h ) ;
2020-06-30 21:31:54 +08:00
// For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui.
2015-10-15 05:01:52 +08:00
io . DisplayFramebufferScale = g_scale ;
2015-10-09 04:38:37 +08:00
// Setup time step
2015-10-15 18:44:30 +08:00
double current_time = s3eTimerGetUST ( ) / 1000.0f ;
2020-06-30 21:31:54 +08:00
io . DeltaTime = g_Time > 0.0 ? ( float ) ( current_time - g_Time ) : ( float ) ( 1.0f / 60.0f ) ;
2015-10-09 04:38:37 +08:00
g_Time = current_time ;
2015-10-15 05:01:52 +08:00
double mouse_x , mouse_y ;
mouse_x = s3ePointerGetX ( ) ;
mouse_y = s3ePointerGetY ( ) ;
2020-06-30 21:31:54 +08:00
io . MousePos = ImVec2 ( ( float ) mouse_x / g_scale . x , ( float ) mouse_y / g_scale . y ) ; // Mouse position (set to -FLT_MAX,-FLT_MAX if no mouse / on another screen, etc.)
2016-03-26 22:43:45 +08:00
for ( int i = 0 ; i < 3 ; i + + )
2015-10-15 18:44:30 +08:00
{
2015-10-09 04:38:37 +08:00
io . MouseDown [ i ] = g_MousePressed [ i ] | | s3ePointerGetState ( ( s3ePointerButton ) i ) ! = S3E_POINTER_STATE_UP ; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
g_MousePressed [ i ] = false ;
}
2015-10-15 18:44:30 +08:00
// TODO: Hide OS mouse cursor if ImGui is drawing it
// s3ePointerSetInt(S3E_POINTER_HIDE_CURSOR,(io.MouseDrawCursor ? 0 : 1));
2015-10-09 04:38:37 +08:00
2020-06-30 21:31:54 +08:00
// Show/hide OSD keyboard
2015-10-15 18:44:30 +08:00
if ( io . WantTextInput )
2016-03-26 22:43:45 +08:00
{
2015-10-15 18:44:30 +08:00
// Some text input widget is active?
2016-03-26 22:43:45 +08:00
if ( ! g_osdKeyboardEnabled )
2015-10-15 18:44:30 +08:00
{
g_osdKeyboardEnabled = true ;
s3eKeyboardSetInt ( S3E_KEYBOARD_GET_CHAR , 1 ) ; // show OSD keyboard
2015-10-15 05:01:52 +08:00
}
}
2016-03-26 22:43:45 +08:00
else
2015-10-15 18:44:30 +08:00
{
// No text input widget is active
if ( g_osdKeyboardEnabled )
{
g_osdKeyboardEnabled = false ;
s3eKeyboardSetInt ( S3E_KEYBOARD_GET_CHAR , 0 ) ; // hide OSD keyboard
2015-10-15 05:01:52 +08:00
}
}
2015-10-09 04:38:37 +08:00
}