 src/libbluray/decoders/graphics_controller.c |  125 ++++++++++++++++++--------
 1 files changed, 89 insertions(+), 36 deletions(-)

diff --git a/src/libbluray/decoders/graphics_controller.c b/src/libbluray/decoders/graphics_controller.c
index 5c5d923..8fee2a8 100644
--- a/src/libbluray/decoders/graphics_controller.c
+++ b/src/libbluray/decoders/graphics_controller.c
@@ -31,8 +31,13 @@
 
 #include <inttypes.h>
 
+#ifdef _USRDLL
+#define ERROR(x,...) DEBUG(DBG_BLURAY | DBG_CRIT, x, #__VA_ARGS__)
+#define TRACE(x,...) DEBUG(DBG_BLURAY,            x, #__VA_ARGS__)
+#else	//	#ifdef _USRDLL
 #define ERROR(x,...) DEBUG(DBG_BLURAY | DBG_CRIT, x, ##__VA_ARGS__)
 #define TRACE(x,...) DEBUG(DBG_BLURAY,            x, ##__VA_ARGS__)
+#endif	//	#ifdef _USRDLL
 
 /*
  *
@@ -315,6 +320,7 @@ static void _render_page(GRAPHICS_CONTROLLER *gc,
     unsigned        page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID);
     unsigned        ii;
     unsigned        selected_button_id = bd_psr_read(gc->regs, PSR_SELECTED_BUTTON_ID);
+    int ifound = 0;
 
     if (s->ics->interactive_composition.ui_model == 1 && !gc->popup_visible) {
         TRACE("_render_page(): popup menu not visible\n");
@@ -345,6 +351,9 @@ static void _render_page(GRAPHICS_CONTROLLER *gc,
         selected_button_id = page->default_selected_button_id_ref;
     }
 
+    /* clear page */
+    _gc_clear_osd(gc, 1);
+
     for (ii = 0; ii < page->num_bogs; ii++) {
         BD_IG_BOG    *bog      = &page->bog[ii];
         unsigned      valid_id = gc->enabled_button[ii];
@@ -357,21 +366,42 @@ static void _render_page(GRAPHICS_CONTROLLER *gc,
 
         } else if (button->id == activated_button_id) {
             _render_button(gc, button, palette, BTN_ACTIVATED);
+            ifound = 1;
 
         } else if (button->id == selected_button_id) {
 
             _render_button(gc, button, palette, BTN_SELECTED);
 
             bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, selected_button_id);
-
+    
             if (button->auto_action_flag) {
                 cmds->num_nav_cmds = button->num_nav_cmds;
                 cmds->nav_cmds     = button->nav_cmds;
             }
-
+            ifound = 1;
         } else {
             _render_button(gc, button, palette, BTN_NORMAL);
+        }
+    }
 
+    // check if we had a startup bog, preparing the page (ege some universal BR's like BG-the plan)
+    // note that this may not be needed once the animations work correctly...
+    // this also fixes the case where the PSR register with the selected button id is not in
+    // the current page anymore (which happens after a selection in a sub menu, a play, and then a jump back to main menu)
+    if( (0 == ifound) &&
+        (page->num_bogs == 1) &&
+        (page->default_selected_button_id_ref == page->default_activated_button_id_ref)
+    )
+    {
+        BD_IG_BOG*    bog = &page->bog[0];
+        unsigned      valid_id = gc->enabled_button[0];
+        BD_IG_BUTTON* button = _find_button_bog(bog, valid_id);
+        if( (button) &&
+            (button->auto_action_flag)
+        )
+        {
+            cmds->num_nav_cmds = button->num_nav_cmds;
+            cmds->nav_cmds     = button->nav_cmds;
         }
     }
 }
@@ -383,7 +413,7 @@ static void _render_page(GRAPHICS_CONTROLLER *gc,
 #define VK_IS_NUMERIC(vk) (/*vk >= BD_VK_0  &&*/ vk <= BD_VK_9)
 #define VK_IS_CURSOR(vk)  (vk >= BD_VK_UP && vk <= BD_VK_RIGHT)
 
-static void _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *cmds)
+static int _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *cmds)
 {
     PG_DISPLAY_SET *s          = gc->igs;
     BD_IG_PAGE     *page       = NULL;
@@ -395,7 +425,7 @@ static void _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *c
 
     if (s->ics->interactive_composition.ui_model == 1 && !gc->popup_visible) {
         TRACE("_user_input(): popup menu not visible\n");
-        return;
+        return -1;
     }
 
     TRACE("_user_input(%d)\n", key);
@@ -404,13 +434,13 @@ static void _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *c
     if (!page) {
         ERROR("_user_input(): unknown page id %d (have %d pages)\n",
               page_id, s->ics->interactive_composition.num_pages);
-        return;
+        return -1;
     }
 
     if (key == BD_VK_MOUSE_ACTIVATE) {
         if (!gc->valid_mouse_position) {
             TRACE("_user_input(): BD_VK_MOUSE_ACTIVATE outside of valid buttons\n");
-            return;
+            return -1;
         }
         key = BD_VK_ENTER;
     }
@@ -464,7 +494,12 @@ static void _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *c
         bd_psr_write(gc->regs, PSR_SELECTED_BUTTON_ID, new_btn_id);
 
         _render_page(gc, activated_btn_id, cmds);
+
+        /* found one*/
+        return 1;
     }
+
+    return 0;
 }
 
 static void _reset_enabled_button(GRAPHICS_CONTROLLER *gc)
@@ -645,29 +680,29 @@ static void _update_selected_button(GRAPHICS_CONTROLLER *gc)
         return;
     }
 
-   if (button_id == 0xffff) {
-        PG_DISPLAY_SET *s       = gc->igs;
-        BD_IG_PAGE     *page    = NULL;
-        unsigned        page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID);
-
-        page = _find_page(&s->ics->interactive_composition, page_id);
-        if (!page) {
-            TRACE("_update_enabled_button(): unknown page #%d (have %d pages)\n",
-                  page_id, s->ics->interactive_composition.num_pages);
-            return;
-        }
+    PG_DISPLAY_SET *s       = gc->igs;
+    BD_IG_PAGE     *page    = NULL;
+    unsigned        page_id = bd_psr_read(gc->regs, PSR_MENU_PAGE_ID);
 
-        // run 5.9.8.3
+    page = _find_page(&s->ics->interactive_composition, page_id);
+    if (!page) {
+        TRACE("_update_enabled_button(): unknown page #%d (have %d pages)\n",
+              page_id, s->ics->interactive_composition.num_pages);
+        return;
+    }
 
-        if (_find_button_page(page, page->default_selected_button_id_ref, NULL) &&
-            _is_button_enabled(gc, page, page->default_selected_button_id_ref)) {
+    // run 5.9.8.3
 
+    {
+        if( (button_id == 0xffff) &&
+            (_find_button_page(page, page->default_selected_button_id_ref, NULL)) &&
+            (_is_button_enabled(gc, page, page->default_selected_button_id_ref))
+        )
+        {
             button_id = page->default_selected_button_id_ref;
-
         } else {
             unsigned ii;
             for (ii = 0; ii < page->num_bogs; ii++) {
-
                 BD_IG_BOG *bog = &page->bog[ii];
                 if (_find_button_bog(bog, gc->enabled_button[ii])) {
                     button_id = gc->enabled_button[ii];
@@ -681,7 +716,7 @@ static void _update_selected_button(GRAPHICS_CONTROLLER *gc)
     }
 }
 
-static void _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_CMDS *cmds)
+static int _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_CMDS *cmds)
 {
     PG_DISPLAY_SET *s          = gc->igs;
     BD_IG_PAGE     *page       = NULL;
@@ -696,13 +731,21 @@ static void _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_
     if (!page) {
         ERROR("_mouse_move(): unknown page #%d (have %d pages)\n",
               page_id, s->ics->interactive_composition.num_pages);
-        return;
+        return -1;
     }
 
     for (ii = 0; ii < page->num_bogs; ii++) {
         BD_IG_BOG    *bog      = &page->bog[ii];
-        unsigned      valid_id = gc->enabled_button[ii];
-        BD_IG_BUTTON *button   = _find_button_bog(bog, valid_id);
+        unsigned      valid_id = 0;
+        BD_IG_BUTTON *button = NULL;
+
+        /* sometimes null, not sure why*/
+        if(gc->enabled_button == NULL)
+           continue;
+        valid_id = gc->enabled_button[ii];
+
+        /* get button */
+        button = _find_button_bog(bog, valid_id);
 
         if (!button)
             continue;
@@ -712,22 +755,27 @@ static void _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_
 
         BD_PG_OBJECT *object = _find_object_for_button(s, button, BTN_NORMAL);
         if (!object)
-            continue;
+        {
+            /* try selected then. sometimes normal is -1*/
+            object = _find_object_for_button(s, button, BTN_SELECTED);
+            if (!object)
+               continue;
+        }
 
         if (x >= button->x_pos + object->width || y >= button->y_pos + object->height)
             continue;
 
-        // mouse is over button
+        /* mouse is over button */
 
-        // is button already selected ?
+        /* is button already selected? */
         if (button->id == cur_btn_id) {
             gc->valid_mouse_position = 1;
-            return;
+            return 0;
         }
 
         // can button be selected ?
         if (!_find_object_for_button(s, button, BTN_SELECTED))
-            return;
+            return -1;
 
         new_btn_id = button->id;
         break;
@@ -740,10 +788,14 @@ static void _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_
 
         gc->valid_mouse_position = 1;
     }
+
+     return gc->valid_mouse_position;
 }
 
-void gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS *cmds)
+int gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS *cmds)
 {
+    int iresult = -1;
+
     if (cmds) {
         cmds->num_nav_cmds = 0;
         cmds->nav_cmds     = NULL;
@@ -752,7 +804,7 @@ void gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS
 
     if (!gc || !gc->igs || !gc->igs->ics) {
         TRACE("gc_run(): no interactive composition\n");
-        return;
+        return iresult;
     }
 
     switch (ctrl) {
@@ -763,7 +815,7 @@ void gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS
 
         case GC_CTRL_VK_KEY:
             if (param != BD_VK_POPUP) {
-                _user_input(gc, param, cmds);
+                iresult = _user_input(gc, param, cmds);
                 break;
             }
             param = !gc->popup_visible;
@@ -807,7 +859,8 @@ void gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS
             break;
 
         case GC_CTRL_MOUSE_MOVE:
-          _mouse_move(gc, param >> 16, param & 0xffff, cmds);
-          return;
+          return _mouse_move(gc, param >> 16, param & 0xffff, cmds);
     }
+
+    return iresult;
 }
