Expand Up
@@ -25,6 +25,7 @@
#include "util/macro.h"
#include "util/logging.h"
#include "util/mutex.h"
#include "../register.h"
#include "../keys.h"
Expand All
@@ -42,6 +43,8 @@ struct graphics_controller_s {
BD_REGISTERS * regs ;
BD_MUTEX mutex ;
/* overlay output */
void * overlay_proc_handle ;
void (* overlay_proc )(void * , const struct bd_overlay_s * const );
Expand All
@@ -62,16 +65,128 @@ struct graphics_controller_s {
GRAPHICS_PROCESSOR * igp ;
};
GRAPHICS_CONTROLLER * gc_init (BD_REGISTERS * regs , void * handle , gc_overlay_proc_f func )
/*
* object lookup
*/
static BD_PG_OBJECT * _find_object (PG_DISPLAY_SET * s , unsigned object_id )
{
GRAPHICS_CONTROLLER * p = calloc ( 1 , sizeof ( * p )) ;
unsigned ii ;
p -> regs = regs ;
for (ii = 0 ; ii < s -> num_object ; ii ++ ) {
if (s -> object [ii ].id == object_id ) {
return & s -> object [ii ];
}
}
p -> overlay_proc_handle = handle ;
p -> overlay_proc = func ;
return NULL ;
}
return p ;
static BD_PG_PALETTE * _find_palette (PG_DISPLAY_SET * s , unsigned palette_id )
{
unsigned ii ;
for (ii = 0 ; ii < s -> num_palette ; ii ++ ) {
if (s -> palette [ii ].id == palette_id ) {
return & s -> palette [ii ];
}
}
return NULL ;
}
static BD_IG_BUTTON * _find_button_bog (BD_IG_BOG * bog , unsigned button_id )
{
unsigned ii ;
for (ii = 0 ; ii < bog -> num_buttons ; ii ++ ) {
if (bog -> button [ii ].id == button_id ) {
return & bog -> button [ii ];
}
}
return NULL ;
}
static BD_IG_BUTTON * _find_button_page (BD_IG_PAGE * page , unsigned button_id , unsigned * bog_idx )
{
unsigned ii ;
for (ii = 0 ; ii < page -> num_bogs ; ii ++ ) {
BD_IG_BUTTON * button = _find_button_bog (& page -> bog [ii ], button_id );
if (button ) {
if (bog_idx ) {
* bog_idx = ii ;
}
return button ;
}
}
return NULL ;
}
static BD_IG_PAGE * _find_page (BD_IG_INTERACTIVE_COMPOSITION * c , unsigned page_id )
{
unsigned ii ;
for (ii = 0 ; ii < c -> num_pages ; ii ++ ) {
if (c -> page [ii ].id == page_id ) {
return & c -> page [ii ];
}
}
return NULL ;
}
enum { BTN_NORMAL , BTN_SELECTED , BTN_ACTIVATED };
static BD_PG_OBJECT * _find_object_for_button (PG_DISPLAY_SET * s ,
BD_IG_BUTTON * button , int state )
{
BD_PG_OBJECT * object = NULL ;
unsigned object_id = 0xffff ;
switch (state ) {
case BTN_NORMAL :
object_id = button -> normal_start_object_id_ref ;
break ;
case BTN_SELECTED :
object_id = button -> selected_start_object_id_ref ;
break ;
case BTN_ACTIVATED :
object_id = button -> activated_start_object_id_ref ;
break ;
}
object = _find_object (s , object_id );
return object ;
}
/*
* util
*/
static void _reset_enabled_button (GRAPHICS_CONTROLLER * gc )
{
PG_DISPLAY_SET * s = gc -> igs ;
BD_IG_PAGE * page = NULL ;
unsigned page_id = bd_psr_read (gc -> regs , PSR_MENU_PAGE_ID );
unsigned ii ;
page = _find_page (& s -> ics -> interactive_composition , page_id );
if (!page ) {
ERROR ("_reset_enabled_button(): unknown page #%d (have %d pages)\n" ,
page_id , s -> ics -> interactive_composition .num_pages );
return ;
}
gc -> enabled_button = realloc (gc -> enabled_button ,
page -> num_bogs * sizeof (uint16_t ));
for (ii = 0 ; ii < page -> num_bogs ; ii ++ ) {
gc -> enabled_button [ii ] = page -> bog [ii ].default_valid_button_id_ref ;
}
}
static void _gc_clear_osd (GRAPHICS_CONTROLLER * gc , int plane )
Expand Down
Expand Up
@@ -115,6 +230,24 @@ static void _gc_reset(GRAPHICS_CONTROLLER *gc)
X_FREE (gc -> enabled_button );
}
/*
* init / free
*/
GRAPHICS_CONTROLLER * gc_init (BD_REGISTERS * regs , void * handle , gc_overlay_proc_f func )
{
GRAPHICS_CONTROLLER * p = calloc (1 , sizeof (* p ));
p -> regs = regs ;
p -> overlay_proc_handle = handle ;
p -> overlay_proc = func ;
bd_mutex_init (& p -> mutex );
return p ;
}
void gc_free (GRAPHICS_CONTROLLER * * p )
{
if (p && * p ) {
Expand All
@@ -125,6 +258,8 @@ void gc_free(GRAPHICS_CONTROLLER **p)
(* p )-> overlay_proc ((* p )-> overlay_proc_handle , NULL );
}
bd_mutex_destroy (& (* p )-> mutex );
X_FREE (* p );
}
}
Expand All
@@ -133,20 +268,27 @@ void gc_free(GRAPHICS_CONTROLLER **p)
* graphics stream input
*/
static void _reset_enabled_button (GRAPHICS_CONTROLLER * gc );
void gc_decode_ts (GRAPHICS_CONTROLLER * gc , uint16_t pid , uint8_t * block , unsigned num_blocks , int64_t stc )
{
if (!gc ) {
TRACE ("gc_decode_ts(): no graphics controller\n" );
return ;
}
if (pid >= 0x1400 && pid < 0x1500 ) {
/* IG stream */
if (!gc -> igp ) {
gc -> igp = graphics_processor_init ();
}
bd_mutex_lock (& gc -> mutex );
graphics_processor_decode_ts (gc -> igp , & gc -> igs ,
pid , block , num_blocks ,
stc );
if (!gc -> igs || !gc -> igs -> complete ) {
bd_mutex_unlock (& gc -> mutex );
return ;
}
Expand All
@@ -157,6 +299,8 @@ void gc_decode_ts(GRAPHICS_CONTROLLER *gc, uint16_t pid, uint8_t *block, unsigne
_gc_clear_osd (gc , 1 );
_reset_enabled_button (gc );
bd_mutex_unlock (& gc -> mutex );
}
else if (pid >= 0x1200 && pid < 0x1300 ) {
Expand All
@@ -174,105 +318,6 @@ void gc_decode_ts(GRAPHICS_CONTROLLER *gc, uint16_t pid, uint8_t *block, unsigne
}
}
/*
* object lookup
*/
static BD_PG_OBJECT * _find_object (PG_DISPLAY_SET * s , unsigned object_id )
{
unsigned ii ;
for (ii = 0 ; ii < s -> num_object ; ii ++ ) {
if (s -> object [ii ].id == object_id ) {
return & s -> object [ii ];
}
}
return NULL ;
}
static BD_PG_PALETTE * _find_palette (PG_DISPLAY_SET * s , unsigned palette_id )
{
unsigned ii ;
for (ii = 0 ; ii < s -> num_palette ; ii ++ ) {
if (s -> palette [ii ].id == palette_id ) {
return & s -> palette [ii ];
}
}
return NULL ;
}
static BD_IG_BUTTON * _find_button_bog (BD_IG_BOG * bog , unsigned button_id )
{
unsigned ii ;
for (ii = 0 ; ii < bog -> num_buttons ; ii ++ ) {
if (bog -> button [ii ].id == button_id ) {
return & bog -> button [ii ];
}
}
return NULL ;
}
static BD_IG_BUTTON * _find_button_page (BD_IG_PAGE * page , unsigned button_id , unsigned * bog_idx )
{
unsigned ii ;
for (ii = 0 ; ii < page -> num_bogs ; ii ++ ) {
BD_IG_BUTTON * button = _find_button_bog (& page -> bog [ii ], button_id );
if (button ) {
if (bog_idx ) {
* bog_idx = ii ;
}
return button ;
}
}
return NULL ;
}
static BD_IG_PAGE * _find_page (BD_IG_INTERACTIVE_COMPOSITION * c , unsigned page_id )
{
unsigned ii ;
for (ii = 0 ; ii < c -> num_pages ; ii ++ ) {
if (c -> page [ii ].id == page_id ) {
return & c -> page [ii ];
}
}
return NULL ;
}
enum { BTN_NORMAL , BTN_SELECTED , BTN_ACTIVATED };
static BD_PG_OBJECT * _find_object_for_button (PG_DISPLAY_SET * s ,
BD_IG_BUTTON * button , int state )
{
BD_PG_OBJECT * object = NULL ;
unsigned object_id = 0xffff ;
switch (state ) {
case BTN_NORMAL :
object_id = button -> normal_start_object_id_ref ;
break ;
case BTN_SELECTED :
object_id = button -> selected_start_object_id_ref ;
break ;
case BTN_ACTIVATED :
object_id = button -> activated_start_object_id_ref ;
break ;
}
object = _find_object (s , object_id );
return object ;
}
/*
* IG rendering
*/
Expand Down
Expand Up
@@ -316,7 +361,7 @@ static void _render_page(GRAPHICS_CONTROLLER *gc,
unsigned ii ;
unsigned selected_button_id = bd_psr_read (gc -> regs , PSR_SELECTED_BUTTON_ID );
if (s -> ics -> interactive_composition .ui_model == 1 && !gc -> popup_visible ) {
if (s -> ics -> interactive_composition .ui_model == IG_UI_MODEL_POPUP && !gc -> popup_visible ) {
TRACE ("_render_page(): popup menu not visible\n" );
_gc_clear_osd (gc , 1 );
Expand Down
Expand Up
@@ -383,7 +428,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 ;
Expand All
@@ -393,9 +438,9 @@ static void _user_input(GRAPHICS_CONTROLLER *gc, bd_vk_key_e key, GC_NAV_CMDS *c
unsigned ii ;
int activated_btn_id = -1 ;
if (s -> ics -> interactive_composition .ui_model == 1 && !gc -> popup_visible ) {
if (s -> ics -> interactive_composition .ui_model == IG_UI_MODEL_POPUP && !gc -> popup_visible ) {
TRACE ("_user_input(): popup menu not visible\n" );
return ;
return -1 ;
}
TRACE ("_user_input(%d)\n" , key );
Expand All
@@ -404,13 +449,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 ;
}
Expand Down
Expand Up
@@ -464,29 +509,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 );
}
}
static void _reset_enabled_button (GRAPHICS_CONTROLLER * gc )
{
PG_DISPLAY_SET * s = gc -> igs ;
BD_IG_PAGE * page = NULL ;
unsigned page_id = bd_psr_read (gc -> regs , PSR_MENU_PAGE_ID );
unsigned ii ;
page = _find_page (& s -> ics -> interactive_composition , page_id );
if (!page ) {
ERROR ("_reset_enabled_button(): unknown page #%d (have %d pages)\n" ,
page_id , s -> ics -> interactive_composition .num_pages );
return ;
/* found one*/
return 1 ;
}
gc -> enabled_button = realloc (gc -> enabled_button ,
page -> num_bogs * sizeof (uint16_t ));
for (ii = 0 ; ii < page -> num_bogs ; ii ++ ) {
gc -> enabled_button [ii ] = page -> bog [ii ].default_valid_button_id_ref ;
}
return 0 ;
}
static void _set_button_page (GRAPHICS_CONTROLLER * gc , uint32_t param , GC_NAV_CMDS * cmds )
Expand Down
Expand Up
@@ -681,7 +709,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 ;
Expand All
@@ -696,7 +724,7 @@ 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 ++ ) {
Expand All
@@ -718,12 +746,12 @@ static void _mouse_move(GRAPHICS_CONTROLLER *gc, unsigned x, unsigned y, GC_NAV_
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 ;
}
new_btn_id = button -> id ;
Expand All
@@ -737,19 +765,42 @@ 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 result = -1 ;
if (cmds ) {
cmds -> num_nav_cmds = 0 ;
cmds -> nav_cmds = NULL ;
cmds -> sound_id_ref = -1 ;
}
if (!gc || !gc -> igs || !gc -> igs -> ics ) {
ERROR ("gc_run(): no interactive composition\n" );
return ;
if (!gc ) {
TRACE ("gc_run(): no graphics controller\n" );
return result ;
}
bd_mutex_lock (& gc -> mutex );
/* always accept reset */
switch (ctrl ) {
case GC_CTRL_RESET :
_gc_reset (gc );
bd_mutex_unlock (& gc -> mutex );
return 0 ;
default :;
}
/* other operations require complete display set */
if (!gc -> igs || !gc -> igs -> ics || !gc -> igs -> complete ) {
TRACE ("gc_run(): no interactive composition\n" );
bd_mutex_unlock (& gc -> mutex );
return result ;
}
switch (ctrl ) {
Expand All
@@ -760,14 +811,14 @@ 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 );
result = _user_input (gc , param , cmds );
break ;
}
param = !gc -> popup_visible ;
/* fall thru (BD_VK_POPUP) */
case GC_CTRL_POPUP :
if (! gc -> igs || ! gc -> igs -> ics || gc -> igs -> ics -> interactive_composition .ui_model != 1 ) {
if (gc -> igs -> ics -> interactive_composition .ui_model != IG_UI_MODEL_POPUP ) {
/* not pop-up menu */
break ;
}
Expand All
@@ -786,10 +837,6 @@ void gc_run(GRAPHICS_CONTROLLER *gc, gc_ctrl_e ctrl, uint32_t param, GC_NAV_CMDS
_render_page (gc , 0xffff , cmds );
break ;
case GC_CTRL_RESET :
_gc_reset (gc );
break ;
case GC_CTRL_IG_END :
_update_selected_button (gc );
_render_page (gc , 0xffff , cmds );
Expand All
@@ -804,7 +851,14 @@ 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 ;
result = _mouse_move (gc , param >> 16 , param & 0xffff , cmds );
break ;
case GC_CTRL_RESET :
/* already handled */
break ;
}
bd_mutex_unlock (& gc -> mutex );
return result ;
}