diff --git a/src/emu/cheat.c b/src/emu/cheat.c index 91cd1fcf141..23b3dd28804 100644 --- a/src/emu/cheat.c +++ b/src/emu/cheat.c @@ -522,7 +522,7 @@ void cheat_render_text(running_machine *machine, render_container *container) { /* output the text */ ui_draw_text_full(container, cheatinfo->output[linenum], - 0.0f, (float)linenum * ui_get_line_height(), 1.0f, + 0.0f, (float)linenum * ui_get_line_height(*machine), 1.0f, cheatinfo->justify[linenum], WRAP_NEVER, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, NULL, NULL); } @@ -901,7 +901,7 @@ static void cheat_frame(running_machine &machine) /* set up for accumulating output */ cheatinfo->lastline = 0; - cheatinfo->numlines = floor(1.0f / ui_get_line_height()); + cheatinfo->numlines = floor(1.0f / ui_get_line_height(machine)); cheatinfo->numlines = MIN(cheatinfo->numlines, ARRAY_LENGTH(cheatinfo->output)); for (linenum = 0; linenum < ARRAY_LENGTH(cheatinfo->output); linenum++) cheatinfo->output[linenum].reset(); diff --git a/src/emu/crsshair.c b/src/emu/crsshair.c index 2985bd3be2a..efa031a7b93 100644 --- a/src/emu/crsshair.c +++ b/src/emu/crsshair.c @@ -196,8 +196,8 @@ static void create_bitmap(running_machine *machine, int player) } /* create a texture to reference the bitmap */ - global.texture[player] = render_texture_alloc(render_texture_hq_scale, NULL); - render_texture_set_bitmap(global.texture[player], global.bitmap[player], NULL, TEXFORMAT_ARGB32, NULL); + global.texture[player] = machine->render().texture_alloc(render_texture::hq_scale); + global.texture[player]->set_bitmap(global.bitmap[player], NULL, TEXFORMAT_ARGB32); } @@ -263,8 +263,7 @@ static void crosshair_exit(running_machine &machine) /* free bitmaps and textures for each player */ for (player = 0; player < MAX_PLAYERS; player++) { - if (global.texture[player] != NULL) - render_texture_free(global.texture[player]); + machine.render().texture_free(global.texture[player]); global.texture[player] = NULL; global_free(global.bitmap[player]); @@ -396,11 +395,10 @@ void crosshair_render(screen_device &screen) ((global.screen[player] == &screen) || (global.screen[player] == CROSSHAIR_SCREEN_ALL))) { /* add a quad assuming a 4:3 screen (this is not perfect) */ - render_screen_add_quad(&screen, - global.x[player] - 0.03f, global.y[player] - 0.04f, - global.x[player] + 0.03f, global.y[player] + 0.04f, - MAKE_ARGB(0xc0, global.fade, global.fade, global.fade), - global.texture[player], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + screen.container().add_quad(global.x[player] - 0.03f, global.y[player] - 0.04f, + global.x[player] + 0.03f, global.y[player] + 0.04f, + MAKE_ARGB(0xc0, global.fade, global.fade, global.fade), + global.texture[player], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c index e7deb65a964..dc4e644b6b4 100644 --- a/src/emu/debug/debugcmd.c +++ b/src/emu/debug/debugcmd.c @@ -1114,7 +1114,7 @@ static void execute_comment(running_machine *machine, int ref, int params, const /* Now try adding the comment */ cpu->debug()->comment_add(address, param[1], 0x00ff0000); - cpu->machine->m_debug_view->update_all(DVT_DISASSEMBLY); + cpu->machine->debug_view().update_all(DVT_DISASSEMBLY); } @@ -1138,7 +1138,7 @@ static void execute_comment_del(running_machine *machine, int ref, int params, c /* If it's a number, it must be an address */ /* The bankoff and cbn will be pulled from what's currently active */ cpu->debug()->comment_remove(address); - cpu->machine->m_debug_view->update_all(DVT_DISASSEMBLY); + cpu->machine->debug_view().update_all(DVT_DISASSEMBLY); } @@ -2427,9 +2427,9 @@ static void execute_snap(running_machine *machine, int ref, int params, const ch const char *filename = param[0]; int scrnum = (params > 1) ? atoi(param[1]) : 0; - device_t *screen = machine->m_devicelist.find(SCREEN, scrnum); + screen_device *screen = downcast(machine->m_devicelist.find(SCREEN, scrnum)); - if ((screen == NULL) || !render_is_live_screen(screen)) + if ((screen == NULL) || !machine->render().is_live(*screen)) { debug_console_printf(machine, "Invalid screen number '%d'\n", scrnum); return; diff --git a/src/emu/debug/debugcon.c b/src/emu/debug/debugcon.c index 3b101ac8cf1..78641ed6797 100644 --- a/src/emu/debug/debugcon.c +++ b/src/emu/debug/debugcon.c @@ -382,7 +382,7 @@ CMDERR debug_console_execute_command(running_machine *machine, const char *comma /* update all views */ if (echo) { - machine->m_debug_view->update_all(); + machine->debug_view().update_all(); debugger_refresh_display(machine); } return result; @@ -481,7 +481,7 @@ void CLIB_DECL debug_console_printf(running_machine *machine, const char *format text_buffer_print(console_textbuf, buffer); /* force an update of any console views */ - machine->m_debug_view->update_all(DVT_CONSOLE); + machine->debug_view().update_all(DVT_CONSOLE); } @@ -499,7 +499,7 @@ void CLIB_DECL debug_console_vprintf(running_machine *machine, const char *forma text_buffer_print(console_textbuf, buffer); /* force an update of any console views */ - machine->m_debug_view->update_all(DVT_CONSOLE); + machine->debug_view().update_all(DVT_CONSOLE); } @@ -521,7 +521,7 @@ void CLIB_DECL debug_console_printf_wrap(running_machine *machine, int wrapcol, text_buffer_print_wrap(console_textbuf, buffer, wrapcol); /* force an update of any console views */ - machine->m_debug_view->update_all(DVT_CONSOLE); + machine->debug_view().update_all(DVT_CONSOLE); } @@ -547,7 +547,7 @@ void debug_errorlog_write_line(running_machine &machine, const char *line) text_buffer_print(errorlog_textbuf, line); /* force an update of any log views */ - machine.m_debug_view->update_all(DVT_LOG); + machine.debug_view().update_all(DVT_LOG); } diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index 72abfa14ac6..4802085c9d0 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -1813,8 +1813,8 @@ void device_debug::start_hook(attotime endtime) // check for periodic updates if (&m_device == global->visiblecpu && osd_ticks() > global->last_periodic_update_time + osd_ticks_per_second()/4) { - m_device.machine->m_debug_view->update_all(); - m_device.machine->m_debug_view->flush_osd_updates(); + m_device.machine->debug_view().update_all(); + m_device.machine->debug_view().flush_osd_updates(); global->last_periodic_update_time = osd_ticks(); } @@ -1949,8 +1949,8 @@ void device_debug::instruction_hook(offs_t curpc) // update every 100 steps until we are within 200 of the end else if ((m_flags & DEBUG_FLAG_STEPPING_OUT) == 0 && (m_stepsleft < 200 || m_stepsleft % 100 == 0)) { - m_device.machine->m_debug_view->update_all(); - m_device.machine->m_debug_view->flush_osd_updates(); + m_device.machine->debug_view().update_all(); + m_device.machine->debug_view().flush_osd_updates(); debugger_refresh_display(m_device.machine); } } @@ -1998,7 +1998,7 @@ void device_debug::instruction_hook(offs_t curpc) global->visiblecpu = &m_device; // update all views - m_device.machine->m_debug_view->update_all(); + m_device.machine->debug_view().update_all(); debugger_refresh_display(m_device.machine); // wait for the debugger; during this time, disable sound output @@ -2006,7 +2006,7 @@ void device_debug::instruction_hook(offs_t curpc) while (global->execution_state == EXECUTION_STATE_STOPPED) { // flush any pending updates before waiting again - m_device.machine->m_debug_view->flush_osd_updates(); + m_device.machine->debug_view().flush_osd_updates(); // clear the memory modified flag and wait global->memory_modified = false; @@ -2019,7 +2019,7 @@ void device_debug::instruction_hook(offs_t curpc) // if something modified memory, update the screen if (global->memory_modified) { - m_device.machine->m_debug_view->update_all(DVT_DISASSEMBLY); + m_device.machine->debug_view().update_all(DVT_DISASSEMBLY); debugger_refresh_display(m_device.machine); } diff --git a/src/emu/debugint/debugint.c b/src/emu/debugint/debugint.c index 74f601fe172..0f8569e218c 100644 --- a/src/emu/debugint/debugint.c +++ b/src/emu/debugint/debugint.c @@ -159,8 +159,8 @@ public: { this->target = target; //dv->container = render_target_get_component_container(target, name, &pos); - this->container = render_debug_alloc(target); - this->view = machine->m_debug_view->alloc_view(type, dview_update, this); + this->container = target->debug_alloc(); + this->view = machine->debug_view().alloc_view(type, dview_update, this); this->type = type; this->machine = machine; this->state = flags | VIEW_STATE_NEEDS_UPDATE; @@ -185,8 +185,8 @@ public: } ~DView() { - render_debug_free(this->target, this->container); - machine->m_debug_view->free_view(*this->view); + this->target->debug_free(*this->container); + machine->debug_view().free_view(*this->view); } DView * next; @@ -295,7 +295,7 @@ static void set_focus_view(DView *dv) focus_view = dv; LIST_REMOVE(list, dv, DView); LIST_ADD_FRONT(list, dv, DView); - render_debug_top(dv->target, dv->container); + dv->target->debug_top(*dv->container); } } @@ -364,7 +364,7 @@ static void dview_get_rect(DView *dv, int type, rectangle *rect) static void dview_clear(DView *dv) { - render_container_empty(dv->container); + dv->container->empty(); } static void dview_draw_outlined_box(DView *dv, int rtype, int x, int y, int w, int h, rgb_t bg) @@ -381,7 +381,7 @@ static void dview_draw_box(DView *dv, int rtype, int x, int y, int w, int h, rgb rectangle r; dview_get_rect(dv, rtype, &r); - render_container_add_rect(dv->container, NX(dv, x + r.min_x), NY(dv, y + r.min_y), + dv->container->add_rect(NX(dv, x + r.min_x), NY(dv, y + r.min_y), NX(dv, x + r.min_x + w), NY(dv, y + r.min_y + h), col, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } @@ -391,14 +391,14 @@ static void dview_draw_char(DView *dv, int rtype, int x, int y, int h, rgb_t col rectangle r; dview_get_rect(dv, rtype, &r); - render_container_add_char(dv->container, + dv->container->add_char( NX(dv, x + r.min_x), NY(dv, y + r.min_y), NY(dv, h), debug_font_aspect, //(float) rect_get_height(&dv->bounds) / (float) rect_get_width(&dv->bounds), //render_get_ui_aspect(), col, - debug_font, + *debug_font, ch); } @@ -777,15 +777,15 @@ static void dview_draw(DView *dv) static void dview_size_allocate(DView *dv) { debug_view_xy size, pos, col, vsize; - render_container_user_settings rcus; + render_container::user_settings rcus; rectangle r; - render_container_get_user_settings(dv->container, &rcus); - rcus.xoffset = (float) dv->ofs_x / (float) dv->rt_width; - rcus.yoffset = (float) dv->ofs_y / (float) dv->rt_height; - rcus.xscale = 1.0; //(float) rect_get_width(&dv->bounds) / (float) dv->rt_width; - rcus.yscale = 1.0; //(float) rect_get_height(&dv->bounds) / (float) dv->rt_height; - render_container_set_user_settings(dv->container, &rcus); + dv->container->get_user_settings(rcus); + rcus.m_xoffset = (float) dv->ofs_x / (float) dv->rt_width; + rcus.m_yoffset = (float) dv->ofs_y / (float) dv->rt_height; + rcus.m_xscale = 1.0; //(float) rect_get_width(&dv->bounds) / (float) dv->rt_width; + rcus.m_yscale = 1.0; //(float) rect_get_height(&dv->bounds) / (float) dv->rt_height; + dv->container->set_user_settings(rcus); //printf("%d %d %d %d\n", wpos.min_x, wpos.max_x, wpos.min_y, wpos.max_y); pos = dv->view->visible_position(); @@ -899,7 +899,7 @@ void debugint_init(running_machine *machine) { unicode_char ch; int chw; - debug_font = render_font_alloc("ui.bdf"); //ui_get_font(); + debug_font = render_font_alloc(*machine, "ui.bdf"); //ui_get_font(); debug_font_width = 0; debug_font_height = 15; @@ -908,7 +908,7 @@ void debugint_init(running_machine *machine) list = NULL; focus_view = NULL; - debug_font_aspect = render_get_ui_aspect(); + debug_font_aspect = machine->render().ui_aspect(); for (ch=0;ch<=127;ch++) { @@ -930,14 +930,14 @@ static void set_view_by_name(render_target *target, const char *name) for (i = 0; ; i++ ) { - s = render_target_get_view_name(target, i); + s = target->view_name(i); if (s == NULL) return; //printf("%d %s\n", i, s); if (strcmp(name, s) == 0) { - render_target_set_view(target, i); - //printf("%d\n", render_target_get_view(target) ); + target->set_view(i); + //printf("%d\n", target->view() ); return; } } @@ -977,11 +977,11 @@ static void on_disassembly_window_activate(DView *dv, const ui_menu_event *event render_target *target; const debug_view_source *source; - target = render_get_ui_target(); + target = &dv->machine->render().ui_target(); ndv = dview_alloc(target, dv->machine, DVT_DISASSEMBLY, 0); ndv->editor.active = TRUE; - ndv->editor.container = render_container_get_ui(); + ndv->editor.container = &dv->machine->render().ui_container(); source = ndv->view->source(); dview_set_title(ndv, source->name()); set_focus_view(ndv); @@ -1010,7 +1010,7 @@ static void on_log_window_activate(DView *dv, const ui_menu_event *event) DView *ndv; render_target *target; - target = render_get_ui_target(); + target = &dv->machine->render().ui_target(); ndv = dview_alloc(target, dv->machine, DVT_LOG, 0); dview_set_title(ndv, "Log"); set_focus_view(ndv); @@ -1125,7 +1125,7 @@ static void render_editor(DView_edit *editor) float width, maxwidth; float x1, y1, x2, y2; - render_container_empty(editor->container); + editor->container->empty(); /* get the size of the text */ ui_draw_text_full(editor->container, editor->str, 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, NULL); @@ -1165,7 +1165,7 @@ static void CreateMainMenu(running_machine *machine) if (menu != NULL) ui_menu_free(menu); - menu = ui_menu_alloc(machine, render_container_get_ui(),NULL,NULL); + menu = ui_menu_alloc(machine, &machine->render().ui_container(),NULL,NULL); switch (focus_view->type) { @@ -1348,7 +1348,7 @@ static void handle_menus(running_machine *machine) { const ui_menu_event *event; - render_container_empty(render_container_get_ui()); + machine->render().ui_container().empty(); ui_input_frame_update(*machine); if (menu != NULL) { @@ -1414,7 +1414,8 @@ static void dview_update_view(DView *dv) INT32 old_rt_width = dv->rt_width; INT32 old_rt_height = dv->rt_height; - render_target_get_bounds(dv->target, &dv->rt_width, &dv->rt_height, NULL); + dv->rt_width = dv->target->width(); + dv->rt_height = dv->target->height(); if (dview_is_state(dv, VIEW_STATE_NEEDS_UPDATE) || dv->rt_width != old_rt_width || dv->rt_height != old_rt_height) { dview_size_allocate(dv); @@ -1446,24 +1447,24 @@ void debugint_wait_for_debugger(running_device *device, int firststop) DView *dv; render_target *target; - target = render_get_ui_target(); + target = &device->machine->render().ui_target(); //set_view_by_name(target, "Debug"); dv = dview_alloc(target, device->machine, DVT_DISASSEMBLY, VIEW_STATE_FOLLOW_CPU); dv->editor.active = TRUE; - dv->editor.container = render_container_get_ui(); + dv->editor.container = &device->machine->render().ui_container(); dv = dview_alloc(target, device->machine, DVT_STATE, VIEW_STATE_FOLLOW_CPU); dv = dview_alloc(target, device->machine, DVT_CONSOLE, VIEW_STATE_FOLLOW_CPU); dview_set_title(dv, "Console"); dv->editor.active = TRUE; - dv->editor.container = render_container_get_ui(); + dv->editor.container = &device->machine->render().ui_container(); set_focus_view(dv); } followers_set_cpu(device); - //ui_update_and_render(device->machine, render_container_get_ui()); + //ui_update_and_render(device->machine, &device->machine->render().ui_container()()); update_views(); osd_update(device->machine, FALSE); handle_menus(device->machine); diff --git a/src/emu/drivers/empty.c b/src/emu/drivers/empty.c index 1ca0364a24d..d057e34e5b7 100644 --- a/src/emu/drivers/empty.c +++ b/src/emu/drivers/empty.c @@ -23,7 +23,7 @@ static MACHINE_START( empty ) { /* force the UI to show the game select screen */ - ui_menu_force_game_select(machine, render_container_get_ui()); + ui_menu_force_game_select(machine, &machine->render().ui_container()); } diff --git a/src/emu/emualloc.c b/src/emu/emualloc.c index 49ab8801b22..0baa78ae1c2 100644 --- a/src/emu/emualloc.c +++ b/src/emu/emualloc.c @@ -77,11 +77,11 @@ public: void * m_base; // base of the allocation const char * m_file; // file the allocation was made from int m_line; // line number within that file - int m_id; // unique id + UINT64 m_id; // unique id static const int k_hash_prime = 193; - static int s_curid; // current ID + static UINT64 s_curid; // current ID static osd_lock * s_lock; // lock for managing the list static bool s_lock_alloc; // set to true temporarily during lock allocation static memory_entry *s_hash[k_hash_prime];// hash table based on pointer @@ -110,7 +110,7 @@ resource_pool global_resource_pool; const zeromem_t zeromem = { }; // globals for memory_entry -int memory_entry::s_curid = 0; +UINT64 memory_entry::s_curid = 0; osd_lock *memory_entry::s_lock = NULL; bool memory_entry::s_lock_alloc = false; memory_entry *memory_entry::s_hash[memory_entry::k_hash_prime] = { NULL }; @@ -134,10 +134,10 @@ void *malloc_file_line(size_t size, const char *file, int line) if (result == NULL) return NULL; -#ifdef MAME_DEBUG // add a new entry memory_entry::allocate(size, result, file, line); +#ifdef MAME_DEBUG // randomize the memory rand_memory(result, size); #endif @@ -153,7 +153,6 @@ void *malloc_file_line(size_t size, const char *file, int line) void free_file_line(void *memory, const char *file, int line) { -#ifdef MAME_DEBUG // find the memory entry memory_entry *entry = memory_entry::find(memory); @@ -165,6 +164,7 @@ void free_file_line(void *memory, const char *file, int line) return; } +#ifdef MAME_DEBUG // clear memory to a bogus value memset(memory, 0xfc, entry->m_size); @@ -236,15 +236,42 @@ void resource_pool::add(resource_pool_item &item) int hashval = reinterpret_cast(item.m_ptr) % k_hash_prime; item.m_next = m_hash[hashval]; m_hash[hashval] = &item; - - // insert into ordered list - item.m_ordered_next = NULL; - item.m_ordered_prev = m_ordered_tail; - if (m_ordered_tail != NULL) - m_ordered_tail->m_ordered_next = &item; - m_ordered_tail = &item; - if (m_ordered_head == NULL) + + // fetch the ID of this item's pointer; some implementations put hidden data + // before, so if we don't find it, check 4 bytes ahead + memory_entry *entry = memory_entry::find(item.m_ptr); + if (entry == NULL) + entry = memory_entry::find(reinterpret_cast(item.m_ptr) - sizeof(size_t)); + assert(entry != NULL); + item.m_id = entry->m_id; + + // find the entry to insert after + resource_pool_item *insert_after; + for (insert_after = m_ordered_tail; insert_after != NULL; insert_after = insert_after->m_ordered_prev) + if (insert_after->m_id < item.m_id) + break; + + // insert into the appropriate spot + if (insert_after != NULL) + { + item.m_ordered_next = insert_after->m_ordered_next; + if (item.m_ordered_next != NULL) + item.m_ordered_next->m_ordered_prev = &item; + else + m_ordered_tail = &item; + item.m_ordered_prev = insert_after; + insert_after->m_ordered_next = &item; + } + else + { + item.m_ordered_next = m_ordered_head; + if (item.m_ordered_next != NULL) + item.m_ordered_next->m_ordered_prev = &item; + else + m_ordered_tail = &item; + item.m_ordered_prev = NULL; m_ordered_head = &item; + } osd_lock_release(m_listlock); } @@ -516,7 +543,7 @@ void memory_entry::report_unfreed() if (total == 0) fprintf(stderr, "--- memory leak warning ---\n"); total += entry->m_size; - fprintf(stderr, "allocation #%06d, %d bytes (%s:%d)\n", entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); + fprintf(stderr, "allocation #%06d, %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); } release_lock(); diff --git a/src/emu/emualloc.h b/src/emu/emualloc.h index 074e0c445b6..6df6114f7ca 100644 --- a/src/emu/emualloc.h +++ b/src/emu/emualloc.h @@ -87,7 +87,8 @@ public: m_ordered_next(NULL), m_ordered_prev(NULL), m_ptr(ptr), - m_size(size) { } + m_size(size), + m_id(~(UINT64)0) { } virtual ~resource_pool_item() { } resource_pool_item * m_next; @@ -95,6 +96,7 @@ public: resource_pool_item * m_ordered_prev; void * m_ptr; size_t m_size; + UINT64 m_id; }; diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 2e91ee19b7a..b579972d2df 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -381,17 +381,6 @@ public: void reset() { while (m_head != NULL) remove(*m_head); } - int index(T *object) const - { - int num = 0; - for (T *cur = m_head; cur != NULL; cur = cur->m_next) - if (cur == object) - return num; - else - num++; - return -1; - } - T &prepend(T &object) { object.m_next = m_head; @@ -401,6 +390,20 @@ public: m_count++; return object; } + + void prepend_list(simple_list &list) + { + int count = list.count(); + if (count == 0) + return; + T *tail = list.last(); + T *head = list.detach_all(); + tail->m_next = m_head; + m_head = head; + if (m_tail == NULL) + m_tail = tail; + m_count += count; + } T &append(T &object) { @@ -413,7 +416,35 @@ public: return object; } - void detach(T &object) + void append_list(simple_list &list) + { + int count = list.count(); + if (count == 0) + return; + T *tail = list.last(); + T *head = list.detach_all(); + if (m_tail != NULL) + m_tail->m_next = head; + else + m_head = head; + m_tail = tail; + m_count += count; + } + + T *detach_head() + { + T *result = m_head; + if (result != NULL) + { + m_head = result->m_next; + m_count--; + if (m_head == NULL) + m_tail = NULL; + } + return result; + } + + T &detach(T &object) { T *prev = NULL; for (T *cur = m_head; cur != NULL; prev = cur, cur = cur->m_next) @@ -426,8 +457,17 @@ public: if (m_tail == &object) m_tail = prev; m_count--; - return; + return object; } + return object; + } + + T *detach_all() + { + T *result = m_head; + m_head = m_tail = NULL; + m_count = 0; + return result; } void remove(T &object) @@ -435,7 +475,7 @@ public: detach(object); pool_free(m_pool, &object); } - + T *find(int index) const { for (T *cur = m_head; cur != NULL; cur = cur->m_next) @@ -443,6 +483,48 @@ public: return cur; return NULL; } + + int indexof(const T &object) const + { + int index = 0; + for (T *cur = m_head; cur != NULL; cur = cur->m_next) + { + if (cur == &object) + return index; + index++; + } + return -1; + } +}; + + +// ======================> fixed_allocator + +template +class fixed_allocator +{ + DISABLE_COPYING(fixed_allocator); + +public: + fixed_allocator(resource_pool &pool = global_resource_pool) + : m_pool(pool), + m_freelist(pool) { } + + T *alloc() + { + T *result = m_freelist.detach_head(); + if (result == NULL) + result = m_pool.add_object(new T); + return result; + } + + void reclaim(T *item) { if (item != NULL) m_freelist.append(*item); } + void reclaim(T &item) { m_freelist.append(item); } + void reclaim_all(simple_list &list) { m_freelist.append_list(list); } + +private: + resource_pool &m_pool; + simple_list m_freelist; }; diff --git a/src/emu/inptport.c b/src/emu/inptport.c index ff44b9f09fd..f8754de707d 100644 --- a/src/emu/inptport.c +++ b/src/emu/inptport.c @@ -2490,7 +2490,8 @@ g_profiler.start(PROFILER_INPUT); { const char *tag = NULL; input_port_value mask; - if (render_target_map_point_input(mouse_target, mouse_target_x, mouse_target_y, &tag, &mask, NULL, NULL)) + float x, y; + if (mouse_target->map_point_input(mouse_target_x, mouse_target_y, tag, mask, x, y)) mouse_field = input_field_by_tag_and_mask(machine->m_portlist, tag, mask); } diff --git a/src/emu/machine.c b/src/emu/machine.c index 63e76d76e61..faa39f1ff01 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -173,7 +173,6 @@ running_machine::running_machine(const machine_config &_config, core_options &op generic_machine_data(NULL), generic_video_data(NULL), generic_audio_data(NULL), - m_debug_view(NULL), m_logerror_list(NULL), m_scheduler(*this), m_options(options), @@ -190,7 +189,9 @@ running_machine::running_machine(const machine_config &_config, core_options &op m_saveload_schedule_time(attotime_zero), m_saveload_searchpath(NULL), m_rand_seed(0x9d14abd7), - m_driver_device(NULL) + m_driver_device(NULL), + m_render(NULL), + m_debug_view(NULL) { memset(gfx, 0, sizeof(gfx)); memset(&generic, 0, sizeof(generic)); @@ -271,7 +272,7 @@ void running_machine::start() state_init(this); state_save_allow_registration(this, true); palette_init(this); - render_init(this); + m_render = auto_alloc(this, render_manager(*this)); ui_init(this); generic_machine_init(this); generic_video_init(this); @@ -453,7 +454,7 @@ void running_machine::schedule_exit() if (m_exit_to_game_select && options_get_string(&m_options, OPTION_GAMENAME)[0] != 0) { options_set_string(&m_options, OPTION_GAMENAME, "", OPTION_PRIORITY_CMDLINE); - ui_menu_force_game_select(this, render_container_get_ui()); + ui_menu_force_game_select(this, &render().ui_container()); } // otherwise, exit for real diff --git a/src/emu/machine.h b/src/emu/machine.h index 3c298a21ebd..d2d1f85a799 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -181,6 +181,7 @@ const int DEBUG_FLAG_OSD_ENABLED = 0x00001000; // The OSD debugger is enabled class gfx_element; class colortable_t; class debug_view_manager; +class render_manager; typedef struct _mame_private mame_private; typedef struct _cpuexec_private cpuexec_private; @@ -329,6 +330,8 @@ class running_machine : public bindable_object { DISABLE_COPYING(running_machine); + friend void debugger_init(running_machine *machine); + typedef void (*notify_callback)(running_machine &machine); typedef void (*logerror_callback)(running_machine &machine, const char *string); @@ -381,6 +384,10 @@ public: // regions region_info *region_alloc(const char *name, UINT32 length, UINT32 flags); void region_free(const char *name); + + // managers + render_manager &render() const { assert(m_render != NULL); return *m_render; } + debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; } // misc void CLIB_DECL logerror(const char *format, ...); @@ -449,8 +456,6 @@ public: generic_video_private * generic_video_data; // internal data from video/generic.c generic_audio_private * generic_audio_data; // internal data from audio/generic.c - debug_view_manager * m_debug_view; // internal data from debugvw.c - // driver-specific information driver_device *driver_data() const { return m_driver_device; } @@ -520,6 +525,8 @@ private: time_t m_base_time; driver_device * m_driver_device; + render_manager * m_render; // internal data from render.c + debug_view_manager * m_debug_view; // internal data from debugvw.c }; diff --git a/src/emu/machine/ldcore.c b/src/emu/machine/ldcore.c index e1e6528ade4..5629684f659 100644 --- a/src/emu/machine/ldcore.c +++ b/src/emu/machine/ldcore.c @@ -1246,22 +1246,22 @@ VIDEO_UPDATE( laserdisc ) if (overbitmap != NULL) { if (overbitmap->format == BITMAP_FORMAT_INDEXED16) - render_texture_set_bitmap(ldcore->overtex, overbitmap, &ldcore->config.overclip, TEXFORMAT_PALETTEA16, laserdisc->machine->palette); + ldcore->overtex->set_bitmap(overbitmap, &ldcore->config.overclip, TEXFORMAT_PALETTEA16, laserdisc->machine->palette); else if (overbitmap->format == BITMAP_FORMAT_RGB32) - render_texture_set_bitmap(ldcore->overtex, overbitmap, &ldcore->config.overclip, TEXFORMAT_ARGB32, NULL); + ldcore->overtex->set_bitmap(overbitmap, &ldcore->config.overclip, TEXFORMAT_ARGB32); } /* get the laserdisc video */ laserdisc_get_video(laserdisc, &vidbitmap); if (vidbitmap != NULL) - render_texture_set_bitmap(ldcore->videotex, vidbitmap, NULL, TEXFORMAT_YUY16, ldcore->videopalette); + ldcore->videotex->set_bitmap(vidbitmap, NULL, TEXFORMAT_YUY16, ldcore->videopalette); /* reset the screen contents */ - render_container_empty(render_container_get_screen(screen)); + screen->container().empty(); /* add the video texture */ if (ldcore->videoenable) - render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), ldcore->videotex, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); + screen->container().add_quad(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), ldcore->videotex, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); /* add the overlay */ if (ldcore->overenable && overbitmap != NULL) @@ -1270,7 +1270,7 @@ VIDEO_UPDATE( laserdisc ) float y0 = 0.5f - 0.5f * ldcore->config.overscaley + ldcore->config.overposy; float x1 = x0 + ldcore->config.overscalex; float y1 = y0 + ldcore->config.overscaley; - render_screen_add_quad(screen, x0, y0, x1, y1, MAKE_ARGB(0xff,0xff,0xff,0xff), ldcore->overtex, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1)); + screen->container().add_quad(x0, y0, x1, y1, MAKE_ARGB(0xff,0xff,0xff,0xff), ldcore->overtex, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1)); } /* swap to the next bitmap */ @@ -1418,7 +1418,7 @@ static void init_video(running_device *device) /* allocate texture for rendering */ ldcore->videoenable = TRUE; - ldcore->videotex = render_texture_alloc(NULL, NULL); + ldcore->videotex = device->machine->render().texture_alloc(); if (ldcore->videotex == NULL) fatalerror("Out of memory allocating video texture"); @@ -1435,7 +1435,7 @@ static void init_video(running_device *device) ldcore->overenable = TRUE; ldcore->overbitmap[0] = auto_bitmap_alloc(device->machine, ldcore->config.overwidth, ldcore->config.overheight, (bitmap_format)ldcore->config.overformat); ldcore->overbitmap[1] = auto_bitmap_alloc(device->machine, ldcore->config.overwidth, ldcore->config.overheight, (bitmap_format)ldcore->config.overformat); - ldcore->overtex = render_texture_alloc(NULL, NULL); + ldcore->overtex = device->machine->render().texture_alloc(); if (ldcore->overtex == NULL) fatalerror("Out of memory allocating overlay texture"); } @@ -1536,12 +1536,10 @@ static DEVICE_STOP( laserdisc ) chd_async_complete(ldcore->disc); /* free any textures and palettes */ - if (ldcore->videotex != NULL) - render_texture_free(ldcore->videotex); + device->machine->render().texture_free(ldcore->videotex); if (ldcore->videopalette != NULL) palette_deref(ldcore->videopalette); - if (ldcore->overtex != NULL) - render_texture_free(ldcore->overtex); + device->machine->render().texture_free(ldcore->overtex); } diff --git a/src/emu/render.c b/src/emu/render.c index a1a537d5b0a..a3a74f3c723 100644 --- a/src/emu/render.c +++ b/src/emu/render.c @@ -4,8 +4,36 @@ Core rendering system. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. **************************************************************************** @@ -48,16 +76,9 @@ -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -#define MAX_TEXTURE_SCALES 8 -#define TEXTURE_GROUP_SIZE 256 - -#define NUM_PRIMLISTS 3 - -#define MAX_CLEAR_EXTENTS 1000 +//************************************************************************** +// CONSTANTS +//************************************************************************** #define INTERNAL_FLAG_CHAR 0x00000001 @@ -79,2707 +100,561 @@ enum -/*************************************************************************** - MACROS -***************************************************************************/ +//************************************************************************** +// MACROS +//************************************************************************** #define ISWAP(var1, var2) do { int temp = var1; var1 = var2; var2 = temp; } while (0) #define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0) -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/* typedef struct _render_container render_container; -- defined in render.h */ -typedef struct _object_transform object_transform; -typedef struct _scaled_texture scaled_texture; -typedef struct _container_item container_item; - - -/* a render_ref is an abstract reference to an internal object of some sort */ -struct _render_ref +// an object_transform is used to track transformations when building an object list +struct object_transform { - render_ref * next; /* link to the next reference */ - void * refptr; /* reference pointer */ -}; - - -/* an object_transform is used to track transformations when building an object list */ -struct _object_transform -{ - float xoffs, yoffs; /* offset transforms */ - float xscale, yscale; /* scale transforms */ - render_color color; /* color transform */ - int orientation; /* orientation transform */ - int no_center; /* center the container? */ -}; - - -/* a scaled_texture contains a single scaled entry for a texture */ -struct _scaled_texture -{ - bitmap_t * bitmap; /* final bitmap */ - UINT32 seqid; /* sequence number */ -}; - - -/* a render_texture is used to track transformations when building an object list */ -struct render_texture -{ - render_texture * next; /* next texture (for free list) */ - render_texture * base; /* pointer to base of texture group */ - bitmap_t * bitmap; /* pointer to the original bitmap */ - rectangle sbounds; /* source bounds within the bitmap */ - palette_t * palette; /* palette associated with the texture */ - int format; /* format of the texture data */ - texture_scaler_func scaler; /* scaling callback */ - void * param; /* scaling callback parameter */ - UINT32 curseq; /* current sequence number */ - scaled_texture scaled[MAX_TEXTURE_SCALES]; /* array of scaled variants of this texture */ - rgb_t * bcglookup; /* dynamically allocated B/C/G lookup table */ - UINT32 bcglookup_entries; /* number of B/C/G lookup entries allocated */ -}; - - -/* a render_target describes a surface that is being rendered to */ -class render_target -{ -public: - render_target * next; /* keep a linked list of targets */ - running_machine * machine; /* pointer to the machine we are connected with */ - layout_view * curview; /* current view */ - layout_file * filelist; /* list of layout files */ - UINT32 flags; /* creation flags */ - render_primitive_list primlist[NUM_PRIMLISTS];/* list of primitives */ - int listindex; /* index of next primlist to use */ - INT32 width; /* width in pixels */ - INT32 height; /* height in pixels */ - render_bounds bounds; /* bounds of the target */ - float pixel_aspect; /* aspect ratio of individual pixels */ - float max_refresh; /* maximum refresh rate, 0 or if none */ - int orientation; /* orientation */ - int layerconfig; /* layer configuration */ - layout_view * base_view; /* the view at the time of first frame */ - int base_orientation; /* the orientation at the time of first frame */ - int base_layerconfig; /* the layer configuration at the time of first frame */ - int maxtexwidth; /* maximum width of a texture */ - int maxtexheight; /* maximum height of a texture */ - render_container * debug_containers; -}; - - -/* a container_item describes a high level primitive that is added to a container */ -struct _container_item -{ - container_item * next; /* pointer to the next element in the list */ - UINT8 type; /* type of element */ - render_bounds bounds; /* bounds of the element */ - render_color color; /* RGBA factors */ - UINT32 flags; /* option flags */ - UINT32 internal; /* internal flags */ - float width; /* width of the line (lines only) */ - render_texture * texture; /* pointer to the source texture (quads only) */ -}; - - -/* a render_container holds a list of items and an orientation for the entire collection */ -struct _render_container -{ - render_container * next; /* the next container in the list */ - container_item * itemlist; /* head of the item list */ - container_item ** nextitem; /* pointer to the next item to add */ - screen_device *screen; /* the screen device */ - int orientation; /* orientation of the container */ - float brightness; /* brightness of the container */ - float contrast; /* contrast of the container */ - float gamma; /* gamma of the container */ - float xscale; /* X scale factor of the container */ - float yscale; /* Y scale factor of the container */ - float xoffset; /* X offset of the container */ - float yoffset; /* Y offset of the container */ - bitmap_t * overlaybitmap; /* overlay bitmap */ - render_texture * overlaytexture; /* overlay texture */ - palette_client * palclient; /* client to the system palette */ - rgb_t bcglookup256[0x400];/* lookup table for brightness/contrast/gamma */ - rgb_t bcglookup32[0x80]; /* lookup table for brightness/contrast/gamma */ - rgb_t bcglookup[0x10000]; /* full palette lookup with bcg adjustements */ + float xoffs, yoffs; // offset transforms + float xscale, yscale; // scale transforms + render_color color; // color transform + int orientation; // orientation transform + bool no_center; // center the container? }; -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* array of live targets */ -static render_target *targetlist; -static render_target *ui_target; - -/* free lists */ -static render_primitive *render_primitive_free_list; -static container_item *container_item_free_list; -static render_ref *render_ref_free_list; -static render_texture *render_texture_free_list; - -/* containers for the UI and for screens */ -static render_container *ui_container; -static render_container *screen_container_list; -static bitmap_t *screen_overlay; - -/* variables for tracking extents to clear */ -static INT32 clear_extents[MAX_CLEAR_EXTENTS]; -static INT32 clear_extent_count; - -/* precomputed UV coordinates for various orientations */ +// precomputed UV coordinates for various orientations static const render_quad_texuv oriented_texcoords[8] = { - { { 0,0 }, { 1,0 }, { 0,1 }, { 1,1 } }, /* 0 */ - { { 1,0 }, { 0,0 }, { 1,1 }, { 0,1 } }, /* ORIENTATION_FLIP_X */ - { { 0,1 }, { 1,1 }, { 0,0 }, { 1,0 } }, /* ORIENTATION_FLIP_Y */ - { { 1,1 }, { 0,1 }, { 1,0 }, { 0,0 } }, /* ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y */ - { { 0,0 }, { 0,1 }, { 1,0 }, { 1,1 } }, /* ORIENTATION_SWAP_XY */ - { { 0,1 }, { 0,0 }, { 1,1 }, { 1,0 } }, /* ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X */ - { { 1,0 }, { 1,1 }, { 0,0 }, { 0,1 } }, /* ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y */ - { { 1,1 }, { 1,0 }, { 0,1 }, { 0,0 } } /* ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y */ + { { 0,0 }, { 1,0 }, { 0,1 }, { 1,1 } }, // 0 + { { 1,0 }, { 0,0 }, { 1,1 }, { 0,1 } }, // ORIENTATION_FLIP_X + { { 0,1 }, { 1,1 }, { 0,0 }, { 1,0 } }, // ORIENTATION_FLIP_Y + { { 1,1 }, { 0,1 }, { 1,0 }, { 0,0 } }, // ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y + { { 0,0 }, { 0,1 }, { 1,0 }, { 1,1 } }, // ORIENTATION_SWAP_XY + { { 0,1 }, { 0,0 }, { 1,1 }, { 1,0 } }, // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X + { { 1,0 }, { 1,1 }, { 0,0 }, { 0,1 } }, // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y + { { 1,1 }, { 1,0 }, { 0,1 }, { 0,0 } } // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y }; -/* layer orders */ +// layer orders static const int layer_order_standard[] = { ITEM_LAYER_SCREEN, ITEM_LAYER_OVERLAY, ITEM_LAYER_BACKDROP, ITEM_LAYER_BEZEL }; static const int layer_order_alternate[] = { ITEM_LAYER_BACKDROP, ITEM_LAYER_SCREEN, ITEM_LAYER_OVERLAY, ITEM_LAYER_BEZEL }; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** -/* core system */ -static void render_exit(running_machine &machine); -static void render_load(running_machine *machine, int config_type, xml_data_node *parentnode); -static void render_save(running_machine *machine, int config_type, xml_data_node *parentnode); +//------------------------------------------------- +// apply_orientation - apply orientation to a +// set of bounds +//------------------------------------------------- -/* render targets */ -static void release_render_list(render_primitive_list *list); -static int load_layout_files(render_target *target, const char *layoutfile, int singlefile); -static void add_container_primitives(render_target *target, render_primitive_list *list, const object_transform *xform, render_container *container, int blendmode); -static void add_element_primitives(render_target *target, render_primitive_list *list, const object_transform *xform, const layout_element *element, int state, int blendmode); -static void add_clear_and_optimize_primitive_list(render_target *target, render_primitive_list *list); - -/* render references */ -static void invalidate_all_render_ref(void *refptr); - -/* render textures */ -static int texture_get_scaled(render_texture *texture, UINT32 dwidth, UINT32 dheight, render_texinfo *texinfo, render_ref **reflist); -static const rgb_t *texture_get_adjusted_palette(render_texture *texture, render_container *container); - -/* render containers */ -static render_container *render_container_alloc(running_machine *machine); -static void render_container_free(render_container *container); -static container_item *render_container_item_add_generic(render_container *container, UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb); -static void render_container_overlay_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); -static void render_container_recompute_lookups(render_container *container); -static void render_container_update_palette(render_container *container); - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - apply_orientation - apply orientation to a - set of bounds --------------------------------------------------*/ - -INLINE void apply_orientation(render_bounds *bounds, int orientation) +inline void apply_orientation(render_bounds &bounds, int orientation) { - /* swap first */ + // swap first if (orientation & ORIENTATION_SWAP_XY) { - FSWAP(bounds->x0, bounds->y0); - FSWAP(bounds->x1, bounds->y1); + FSWAP(bounds.x0, bounds.y0); + FSWAP(bounds.x1, bounds.y1); } - /* apply X flip */ + // apply X flip if (orientation & ORIENTATION_FLIP_X) { - bounds->x0 = 1.0f - bounds->x0; - bounds->x1 = 1.0f - bounds->x1; + bounds.x0 = 1.0f - bounds.x0; + bounds.x1 = 1.0f - bounds.x1; } - /* apply Y flip */ + // apply Y flip if (orientation & ORIENTATION_FLIP_Y) { - bounds->y0 = 1.0f - bounds->y0; - bounds->y1 = 1.0f - bounds->y1; + bounds.y0 = 1.0f - bounds.y0; + bounds.y1 = 1.0f - bounds.y1; } } -/*------------------------------------------------- - normalize_bounds - normalize bounds so that - x0/y0 are less than x1/y1 --------------------------------------------------*/ +//------------------------------------------------- +// normalize_bounds - normalize bounds so that +// x0/y0 are less than x1/y1 +//------------------------------------------------- -INLINE void normalize_bounds(render_bounds *bounds) +inline void normalize_bounds(render_bounds &bounds) { - if (bounds->x0 > bounds->x1) - FSWAP(bounds->x0, bounds->x1); - if (bounds->y0 > bounds->y1) - FSWAP(bounds->y0, bounds->y1); + if (bounds.x0 > bounds.x1) + FSWAP(bounds.x0, bounds.x1); + if (bounds.y0 > bounds.y1) + FSWAP(bounds.y0, bounds.y1); } -/*------------------------------------------------- - alloc_container_item - allocate a new - container item object ---------------------------------------------------*/ +//------------------------------------------------- +// get_layer_and_blendmode - return the +// appropriate layer index and blendmode +//------------------------------------------------- -INLINE container_item *alloc_container_item(void) +inline int get_layer_and_blendmode(const layout_view &view, int index, int &blendmode) { - container_item *result = container_item_free_list; + const int *layer_order = layer_order_standard; + int layer; - /* allocate from the free list if we can; otherwise, malloc a new item */ - if (result != NULL) - container_item_free_list = result->next; + // if we have multiple backdrop pieces and no overlays, render: + // backdrop (add) + screens (add) + bezels (alpha) + // else render: + // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + + if (view.itemlist[ITEM_LAYER_BACKDROP] != NULL && view.itemlist[ITEM_LAYER_BACKDROP]->next != NULL && view.itemlist[ITEM_LAYER_OVERLAY] == NULL) + layer_order = layer_order_alternate; + + // select the layer + layer = layer_order[index]; + + // pick a blendmode + if (layer == ITEM_LAYER_SCREEN && layer_order == layer_order_standard) + blendmode = -1; + else if (layer == ITEM_LAYER_SCREEN || (layer == ITEM_LAYER_BACKDROP && layer_order == layer_order_standard)) + blendmode = BLENDMODE_ADD; + else if (layer == ITEM_LAYER_OVERLAY) + blendmode = BLENDMODE_RGB_MULTIPLY; else - result = global_alloc(container_item); + blendmode = BLENDMODE_ALPHA; - memset(result, 0, sizeof(*result)); - return result; + return layer; } -/*------------------------------------------------- - container_item_free - free a previously - allocated render element object --------------------------------------------------*/ -INLINE void free_container_item(container_item *item) +//************************************************************************** +// RENDER PRIMITIVE +//************************************************************************** + +//------------------------------------------------- +// reset - reset the state of a primitive after +// it is re-allocated +//------------------------------------------------- + +void render_primitive::reset() { - item->next = container_item_free_list; - container_item_free_list = item; + memset(&type, 0, FPTR(&texcoords + 1) - FPTR(&type)); } -/*------------------------------------------------- - alloc_render_primitive - allocate a new empty - element object --------------------------------------------------*/ -INLINE render_primitive *alloc_render_primitive(int type) +//************************************************************************** +// RENDER PRIMITIVE LIST +//************************************************************************** + +//------------------------------------------------- +// render_primitive_list - constructor +//------------------------------------------------- + +render_primitive_list::render_primitive_list() + : m_lock(osd_lock_alloc()) { - render_primitive *result = render_primitive_free_list; +} - /* allocate from the free list if we can; otherwise, malloc a new item */ - if (result != NULL) - render_primitive_free_list = result->next; - else - result = global_alloc(render_primitive); - /* clear to 0 */ - memset(result, 0, sizeof(*result)); +//------------------------------------------------- +// ~render_primitive_list - destructor +//------------------------------------------------- + +render_primitive_list::~render_primitive_list() +{ + release_all(); + osd_lock_free(m_lock); +} + + +//------------------------------------------------- +// add_reference - add a new reference +//------------------------------------------------- + +inline void render_primitive_list::add_reference(void *refptr) +{ + // skip if we already have one + if (has_reference(refptr)) + return; + + // set the refptr and link us into the list + reference *ref = m_reference_allocator.alloc(); + ref->m_refptr = refptr; + m_reflist.append(*ref); +} + + +//------------------------------------------------- +// has_reference - find a refptr in a reference +// list +//------------------------------------------------- + +inline bool render_primitive_list::has_reference(void *refptr) const +{ + // skip if we already have one + for (reference *ref = m_reflist.first(); ref != NULL; ref = ref->next()) + if (ref->m_refptr == refptr) + return true; + return false; +} + + +//------------------------------------------------- +// alloc - allocate a new empty primitive +//------------------------------------------------- + +inline render_primitive *render_primitive_list::alloc(render_primitive::primitive_type type) +{ + render_primitive *result = m_primitive_allocator.alloc(); + result->reset(); result->type = type; return result; } -/*------------------------------------------------- - append_render_primitive - append a primitive - to the end of the list --------------------------------------------------*/ +//------------------------------------------------- +// release_all - release the contents of +// a render list +//------------------------------------------------- -INLINE void append_render_primitive(render_primitive_list *list, render_primitive *prim) +void render_primitive_list::release_all() { - *list->nextptr = prim; - list->nextptr = &prim->next; + // release all the live items while under the lock + acquire_lock(); + m_primitive_allocator.reclaim_all(m_primlist); + m_reference_allocator.reclaim_all(m_reflist); + release_lock(); } -/*------------------------------------------------- - free_render_primitive - free a previously - allocated render element object --------------------------------------------------*/ +//------------------------------------------------- +// append_or_return - append a primitive to the +// end of the list, or return it to the free +// list, based on a flag +//------------------------------------------------- -INLINE void free_render_primitive(render_primitive *element) +void render_primitive_list::append_or_return(render_primitive &prim, bool clipped) { - element->next = render_primitive_free_list; - render_primitive_free_list = element; -} - - -/*------------------------------------------------- - add_render_ref - add a new reference --------------------------------------------------*/ - -INLINE void add_render_ref(render_ref **list, void *refptr) -{ - render_ref *ref; - - /* skip if we already have one */ - for (ref = *list; ref != NULL; ref = ref->next) - if (ref->refptr == refptr) - return; - - /* allocate from the free list if we can; otherwise, malloc a new item */ - ref = render_ref_free_list; - if (ref != NULL) - render_ref_free_list = ref->next; + if (!clipped) + m_primlist.append(prim); else - ref = global_alloc(render_ref); - - /* set the refptr and link us into the list */ - ref->refptr = refptr; - ref->next = *list; - *list = ref; + m_primitive_allocator.reclaim(prim); } -/*------------------------------------------------- - has_render_ref - find a refptr in a reference - list --------------------------------------------------*/ -INLINE int has_render_ref(render_ref *list, void *refptr) +//************************************************************************** +// RENDER TEXTURE +//************************************************************************** + +//------------------------------------------------- +// render_texture - constructor +//------------------------------------------------- + +render_texture::render_texture() { - render_ref *ref; - - /* skip if we already have one */ - for (ref = list; ref != NULL; ref = ref->next) - if (ref->refptr == refptr) - return TRUE; - return FALSE; + // no initialization because we rely on reset() to do it } -/*------------------------------------------------- - free_render_ref - free a previously - allocated render reference --------------------------------------------------*/ +//------------------------------------------------- +// ~render_texture - destructor +//------------------------------------------------- -INLINE void free_render_ref(render_ref *ref) +render_texture::~render_texture() { - ref->next = render_ref_free_list; - render_ref_free_list = ref; -} - - -/*------------------------------------------------- - get_layer_and_blendmode - return the - appropriate layer index and blendmode --------------------------------------------------*/ - -INLINE int get_layer_and_blendmode(const layout_view *view, int index, int *blendmode) -{ - const int *layer_order = layer_order_standard; - int layer; - - /* - if we have multiple backdrop pieces and no overlays, render: - backdrop (add) + screens (add) + bezels (alpha) - else render: - screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) - */ - if (view->itemlist[ITEM_LAYER_BACKDROP] != NULL && view->itemlist[ITEM_LAYER_BACKDROP]->next != NULL && view->itemlist[ITEM_LAYER_OVERLAY] == NULL) - layer_order = layer_order_alternate; - - /* select the layer */ - layer = layer_order[index]; - - /* if we want the blendmode as well, compute it */ - if (blendmode != NULL) + // free all scaled versions + for (int scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) { - /* pick a blendmode */ - if (layer == ITEM_LAYER_SCREEN && layer_order == layer_order_standard) - *blendmode = -1; - else if (layer == ITEM_LAYER_SCREEN || (layer == ITEM_LAYER_BACKDROP && layer_order == layer_order_standard)) - *blendmode = BLENDMODE_ADD; - else if (layer == ITEM_LAYER_OVERLAY) - *blendmode = BLENDMODE_RGB_MULTIPLY; - else - *blendmode = BLENDMODE_ALPHA; - } - return layer; -} - - -/*------------------------------------------------- - get_screen_container_by_index - get the - screen container for this screen index --------------------------------------------------*/ - -INLINE render_container *get_screen_container_by_index(int index) -{ - render_container *container; - - assert(index >= 0); - - /* get the container for the screen index */ - for (container = screen_container_list; container != NULL; container = container->next) - { - if (index == 0) - break; - index--; + m_manager->invalidate_all(m_scaled[scalenum].bitmap); + auto_free(&m_manager->machine(), m_scaled[scalenum].bitmap); } - assert(index == 0); + // invalidate references to the original bitmap as well + m_manager->invalidate_all(m_bitmap); - return container; + // release palette references + if (m_palette != NULL) + palette_deref(m_palette); + + // free any B/C/G lookup tables + auto_free(&m_manager->machine(), m_bcglookup); } +//------------------------------------------------- +// reset - reset the state of a texture after +// it has been re-allocated +//------------------------------------------------- -/*************************************************************************** - CORE IMPLEMENTATION -***************************************************************************/ - -/*------------------------------------------------- - render_init - allocate base structures for - the rendering system --------------------------------------------------*/ - -void render_init(running_machine *machine) +void render_texture::reset(render_manager &manager, texture_scaler_func scaler, void *param) { - render_container **current_container_ptr = &screen_container_list; - - /* make sure we clean up after ourselves */ - machine->add_notifier(MACHINE_NOTIFY_EXIT, render_exit); - - /* set up the list of render targets */ - targetlist = NULL; - - /* zap the free lists */ - render_primitive_free_list = NULL; - container_item_free_list = NULL; - - /* zap more variables */ - ui_target = NULL; - - /* create a UI container */ - ui_container = render_container_alloc(machine); - - /* create a container for each screen and determine its orientation */ - for (screen_device *screendev = screen_first(*machine); screendev != NULL; screendev = screen_next(screendev)) - { - render_container *screen_container = render_container_alloc(machine); - render_container **temp = &screen_container->next; - render_container_user_settings settings; - - /* set the initial orientation and brightness/contrast/gamma */ - render_container_get_user_settings(screen_container, &settings); - settings.orientation = machine->gamedrv->flags & ORIENTATION_MASK; - settings.brightness = options_get_float(machine->options(), OPTION_BRIGHTNESS); - settings.contrast = options_get_float(machine->options(), OPTION_CONTRAST); - settings.gamma = options_get_float(machine->options(), OPTION_GAMMA); - render_container_set_user_settings(screen_container, &settings); - - screen_container->screen = screendev; - - /* link it up */ - *current_container_ptr = screen_container; - current_container_ptr = temp; - } - - /* terminate list */ - *current_container_ptr = NULL; - - /* register callbacks */ - config_register(machine, "video", render_load, render_save); + m_manager = &manager; + memset(&m_next, 0, FPTR(&m_bcglookup_entries + 1) - FPTR(&m_next)); + m_format = TEXFORMAT_ARGB32; + m_scaler = scaler; + m_param = param; } -/*------------------------------------------------- - render_exit - free all rendering data --------------------------------------------------*/ +//------------------------------------------------- +// set_bitmap - set a new source bitmap +//------------------------------------------------- -static void render_exit(running_machine &machine) +void render_texture::set_bitmap(bitmap_t *bitmap, const rectangle *sbounds, int format, palette_t *palette) { - render_texture **texture_ptr; - render_container *container; - - /* free the UI container */ - if (ui_container != NULL) - render_container_free(ui_container); - - /* free the screen container */ - for (container = screen_container_list; container != NULL; ) - { - render_container *temp = container; - container = temp->next; - render_container_free(temp); - } - - /* remove all non-head entries from the texture free list */ - for (texture_ptr = &render_texture_free_list; *texture_ptr != NULL; texture_ptr = &(*texture_ptr)->next) - while (*texture_ptr != NULL && (*texture_ptr)->base != *texture_ptr) - *texture_ptr = (*texture_ptr)->next; - - /* free the targets; this must be done before freeing the texture groups - as that will forcefully free everything, and if it goes first, we may - end up double-freeing textures of the render targets */ - while (targetlist != NULL) - render_target_free(targetlist); - - /* free the screen overlay; similarly, do this before any of the following - calls to avoid double-frees */ - global_free(screen_overlay); - screen_overlay = NULL; - - /* free the texture groups */ - while (render_texture_free_list != NULL) - { - render_texture *temp = render_texture_free_list; - render_texture_free_list = temp->next; - global_free(temp); - } - - /* free the render primitives */ - while (render_primitive_free_list != NULL) - { - render_primitive *temp = render_primitive_free_list; - render_primitive_free_list = temp->next; - global_free(temp); - } - - /* free the render refs */ - while (render_ref_free_list != NULL) - { - render_ref *temp = render_ref_free_list; - render_ref_free_list = temp->next; - global_free(temp); - } - - /* free the container items */ - while (container_item_free_list != NULL) - { - container_item *temp = container_item_free_list; - container_item_free_list = temp->next; - global_free(temp); - } -} - - -/*------------------------------------------------- - render_load - read and apply data from the - configuration file --------------------------------------------------*/ - -static void render_load(running_machine *machine, int config_type, xml_data_node *parentnode) -{ - xml_data_node *targetnode; - xml_data_node *screennode; - xml_data_node *uinode; - int tmpint; - - /* we only care about game files */ - if (config_type != CONFIG_TYPE_GAME) - return; - - /* might not have any data */ - if (parentnode == NULL) - return; - - /* check the UI target */ - uinode = xml_get_sibling(parentnode->child, "interface"); - if (uinode != NULL) - { - render_target *target = render_target_get_indexed(xml_get_attribute_int(uinode, "target", 0)); - if (target != NULL) - render_set_ui_target(target); - } - - /* iterate over target nodes */ - for (targetnode = xml_get_sibling(parentnode->child, "target"); targetnode; targetnode = xml_get_sibling(targetnode->next, "target")) - { - render_target *target = render_target_get_indexed(xml_get_attribute_int(targetnode, "index", -1)); - if (target != NULL) - { - const char *viewname = xml_get_attribute_string(targetnode, "view", NULL); - int viewnum; - - /* find the view */ - if (viewname != NULL) - for (viewnum = 0; viewnum < 1000; viewnum++) - { - const char *testname = render_target_get_view_name(target, viewnum); - if (testname == NULL) - break; - if (!strcmp(viewname, testname)) - { - render_target_set_view(target, viewnum); - break; - } - } - - /* modify the artwork config */ - tmpint = xml_get_attribute_int(targetnode, "backdrops", -1); - if (tmpint == 0) - render_target_set_layer_config(target, target->layerconfig & ~LAYER_CONFIG_ENABLE_BACKDROP); - else if (tmpint == 1) - render_target_set_layer_config(target, target->layerconfig | LAYER_CONFIG_ENABLE_BACKDROP); - - tmpint = xml_get_attribute_int(targetnode, "overlays", -1); - if (tmpint == 0) - render_target_set_layer_config(target, target->layerconfig & ~LAYER_CONFIG_ENABLE_OVERLAY); - else if (tmpint == 1) - render_target_set_layer_config(target, target->layerconfig | LAYER_CONFIG_ENABLE_OVERLAY); - - tmpint = xml_get_attribute_int(targetnode, "bezels", -1); - if (tmpint == 0) - render_target_set_layer_config(target, target->layerconfig & ~LAYER_CONFIG_ENABLE_BEZEL); - else if (tmpint == 1) - render_target_set_layer_config(target, target->layerconfig | LAYER_CONFIG_ENABLE_BEZEL); - - tmpint = xml_get_attribute_int(targetnode, "zoom", -1); - if (tmpint == 0) - render_target_set_layer_config(target, target->layerconfig & ~LAYER_CONFIG_ZOOM_TO_SCREEN); - else if (tmpint == 1) - render_target_set_layer_config(target, target->layerconfig | LAYER_CONFIG_ZOOM_TO_SCREEN); - - /* apply orientation */ - tmpint = xml_get_attribute_int(targetnode, "rotate", -1); - if (tmpint != -1) - { - if (tmpint == 90) - tmpint = ROT90; - else if (tmpint == 180) - tmpint = ROT180; - else if (tmpint == 270) - tmpint = ROT270; - else - tmpint = ROT0; - render_target_set_orientation(target, orientation_add(tmpint, target->orientation)); - - /* apply the opposite orientation to the UI */ - if (target == render_get_ui_target()) - { - render_container_user_settings settings; - - render_container_get_user_settings(ui_container, &settings); - settings.orientation = orientation_add(orientation_reverse(tmpint), settings.orientation); - render_container_set_user_settings(ui_container, &settings); - } - } - } - } - - /* iterate over screen nodes */ - for (screennode = xml_get_sibling(parentnode->child, "screen"); screennode; screennode = xml_get_sibling(screennode->next, "screen")) - { - int index = xml_get_attribute_int(screennode, "index", -1); - render_container *container = get_screen_container_by_index(index); - render_container_user_settings settings; - - /* fetch current settings */ - render_container_get_user_settings(container, &settings); - - /* fetch color controls */ - settings.brightness = xml_get_attribute_float(screennode, "brightness", settings.brightness); - settings.contrast = xml_get_attribute_float(screennode, "contrast", settings.contrast); - settings.gamma = xml_get_attribute_float(screennode, "gamma", settings.gamma); - - /* fetch positioning controls */ - settings.xoffset = xml_get_attribute_float(screennode, "hoffset", settings.xoffset); - settings.xscale = xml_get_attribute_float(screennode, "hstretch", settings.xscale); - settings.yoffset = xml_get_attribute_float(screennode, "voffset", settings.yoffset); - settings.yscale = xml_get_attribute_float(screennode, "vstretch", settings.yscale); - - /* set the new values */ - render_container_set_user_settings(container, &settings); - } -} - - -/*------------------------------------------------- - render_save - save data to the configuration - file --------------------------------------------------*/ - -static void render_save(running_machine *machine, int config_type, xml_data_node *parentnode) -{ - render_target *target; - render_container *container; - int scrnum; - int targetnum = 0; - - /* we only care about game files */ - if (config_type != CONFIG_TYPE_GAME) - return; - - /* write out the interface target */ - target = render_get_ui_target(); - if (target != render_target_get_indexed(0)) - { - xml_data_node *uinode; - - /* find the target index */ - for (targetnum = 0; ; targetnum++) - if (render_target_get_indexed(targetnum) == target) - break; - - /* create a node for it */ - uinode = xml_add_child(parentnode, "interface", NULL); - if (uinode != NULL) - xml_set_attribute_int(uinode, "target", targetnum); - } - - /* iterate over targets */ - for (targetnum = 0; targetnum < 1000; targetnum++) - { - xml_data_node *targetnode; - - /* get this target and break when we fail */ - target = render_target_get_indexed(targetnum); - if (target == NULL) - break; - - /* create a node */ - targetnode = xml_add_child(parentnode, "target", NULL); - if (targetnode != NULL) - { - int changed = FALSE; - - /* output the basics */ - xml_set_attribute_int(targetnode, "index", targetnum); - - /* output the view */ - if (target->curview != target->base_view) - { - xml_set_attribute(targetnode, "view", target->curview->name); - changed = TRUE; - } - - /* output the layer config */ - if (target->layerconfig != target->base_layerconfig) - { - xml_set_attribute_int(targetnode, "backdrops", (target->layerconfig & LAYER_CONFIG_ENABLE_BACKDROP) != 0); - xml_set_attribute_int(targetnode, "overlays", (target->layerconfig & LAYER_CONFIG_ENABLE_OVERLAY) != 0); - xml_set_attribute_int(targetnode, "bezels", (target->layerconfig & LAYER_CONFIG_ENABLE_BEZEL) != 0); - xml_set_attribute_int(targetnode, "zoom", (target->layerconfig & LAYER_CONFIG_ZOOM_TO_SCREEN) != 0); - changed = TRUE; - } - - /* output rotation */ - if (target->orientation != target->base_orientation) - { - int rotate = 0; - if (orientation_add(ROT90, target->base_orientation) == target->orientation) - rotate = 90; - else if (orientation_add(ROT180, target->base_orientation) == target->orientation) - rotate = 180; - else if (orientation_add(ROT270, target->base_orientation) == target->orientation) - rotate = 270; - assert(rotate != 0); - xml_set_attribute_int(targetnode, "rotate", rotate); - changed = TRUE; - } - - /* if nothing changed, kill the node */ - if (!changed) - xml_delete_node(targetnode); - } - } - - /* iterate over screen containers */ - for (container = screen_container_list, scrnum = 0; container != NULL; container = container->next, scrnum++) - { - xml_data_node *screennode; - - /* create a node */ - screennode = xml_add_child(parentnode, "screen", NULL); - - if (screennode != NULL) - { - int changed = FALSE; - - /* output the basics */ - xml_set_attribute_int(screennode, "index", scrnum); - - /* output the color controls */ - if (container->brightness != options_get_float(machine->options(), OPTION_BRIGHTNESS)) - { - xml_set_attribute_float(screennode, "brightness", container->brightness); - changed = TRUE; - } - - if (container->contrast != options_get_float(machine->options(), OPTION_CONTRAST)) - { - xml_set_attribute_float(screennode, "contrast", container->contrast); - changed = TRUE; - } - - if (container->gamma != options_get_float(machine->options(), OPTION_GAMMA)) - { - xml_set_attribute_float(screennode, "gamma", container->gamma); - changed = TRUE; - } - - /* output the positioning controls */ - if (container->xoffset != 0.0f) - { - xml_set_attribute_float(screennode, "hoffset", container->xoffset); - changed = TRUE; - } - - if (container->xscale != 1.0f) - { - xml_set_attribute_float(screennode, "hstretch", container->xscale); - changed = TRUE; - } - - if (container->yoffset != 0.0f) - { - xml_set_attribute_float(screennode, "voffset", container->yoffset); - changed = TRUE; - } - - if (container->yscale != 1.0f) - { - xml_set_attribute_float(screennode, "vstretch", container->yscale); - changed = TRUE; - } - - /* if nothing changed, kill the node */ - if (!changed) - xml_delete_node(screennode); - } - } -} - - -/*------------------------------------------------- - render_is_live_screen - return if the screen - is 'live' --------------------------------------------------*/ - -int render_is_live_screen(device_t *screen) -{ - render_target *target; - int screen_index; - UINT32 bitmask = 0; - - assert(screen != NULL); - assert(screen->machine != NULL); - assert(screen->machine->config != NULL); - - screen_index = screen->machine->m_devicelist.index(SCREEN, screen->tag()); - - assert(screen_index != -1); - - /* iterate over all live targets and or together their screen masks */ - for (target = targetlist; target != NULL; target = target->next) - bitmask |= target->curview->screens; - - return (bitmask & (1 << screen_index)) ? TRUE : FALSE; -} - - -/*------------------------------------------------- - render_get_max_update_rate - return the - smallest maximum update rate across all targets --------------------------------------------------*/ - -float render_get_max_update_rate(void) -{ - render_target *target; - float minimum = 0; - - /* iterate over all live targets and or together their screen masks */ - for (target = targetlist; target != NULL; target = target->next) - if (target->max_refresh != 0) - { - if (minimum == 0) - minimum = target->max_refresh; - else - minimum = MIN(target->max_refresh, minimum); - } - - return minimum; -} - - -/*------------------------------------------------- - render_set_ui_target - select the UI target --------------------------------------------------*/ - -void render_set_ui_target(render_target *target) -{ - assert(target != NULL); - ui_target = target; -} - - -/*------------------------------------------------- - render_get_ui_target - return the UI target --------------------------------------------------*/ - -render_target *render_get_ui_target(void) -{ - assert(ui_target != NULL); - return ui_target; -} - - -/*------------------------------------------------- - render_get_ui_aspect - return the aspect - ratio for UI fonts --------------------------------------------------*/ - -float render_get_ui_aspect(void) -{ - render_target *target = render_get_ui_target(); - if (target != NULL) - { - int orient = orientation_add(target->orientation, ui_container->orientation); - float aspect; - - /* based on the orientation of the target, compute height/width or width/height */ - if (!(orient & ORIENTATION_SWAP_XY)) - aspect = (float)target->height / (float)target->width; - else - aspect = (float)target->width / (float)target->height; - - /* if we have a valid pixel aspect, apply that and return */ - if (target->pixel_aspect != 0.0f) - return aspect / target->pixel_aspect; - - /* if not, clamp for extreme proportions */ - if (aspect < 0.66f) - aspect = 0.66f; - if (aspect > 1.5f) - aspect = 1.5f; - return aspect; - } - - return 1.0f; -} - - - -/*************************************************************************** - RENDER TARGETS -***************************************************************************/ - -/*------------------------------------------------- - render_target_alloc - allocate a new render - target --------------------------------------------------*/ - -render_target *render_target_alloc(running_machine *machine, const char *layoutfile, UINT32 flags) -{ - render_target *target; - render_target **nextptr; - int listnum; - - /* allocate memory for the target */ - target = global_alloc_clear(render_target); - - /* add it to the end of the list */ - for (nextptr = &targetlist; *nextptr != NULL; nextptr = &(*nextptr)->next) ; - *nextptr = target; - - /* fill in the basics with reasonable defaults */ - target->machine = machine; - target->flags = flags; - target->width = 640; - target->height = 480; - target->pixel_aspect = 0.0f; - target->orientation = ROT0; - target->layerconfig = LAYER_CONFIG_DEFAULT; - target->maxtexwidth = 65536; - target->maxtexheight = 65536; - - /* determine the base layer configuration based on options */ - target->base_layerconfig = LAYER_CONFIG_DEFAULT; - if (!options_get_bool(machine->options(), OPTION_USE_BACKDROPS)) target->base_layerconfig &= ~LAYER_CONFIG_ENABLE_BACKDROP; - if (!options_get_bool(machine->options(), OPTION_USE_OVERLAYS)) target->base_layerconfig &= ~LAYER_CONFIG_ENABLE_OVERLAY; - if (!options_get_bool(machine->options(), OPTION_USE_BEZELS)) target->base_layerconfig &= ~LAYER_CONFIG_ENABLE_BEZEL; - if (options_get_bool(machine->options(), OPTION_ARTWORK_CROP)) target->base_layerconfig |= LAYER_CONFIG_ZOOM_TO_SCREEN; - - /* determine the base orientation based on options */ - target->orientation = ROT0; - if (!options_get_bool(machine->options(), OPTION_ROTATE)) - target->base_orientation = orientation_reverse(machine->gamedrv->flags & ORIENTATION_MASK); - - /* rotate left/right */ - if (options_get_bool(machine->options(), OPTION_ROR) || (options_get_bool(machine->options(), OPTION_AUTOROR) && (machine->gamedrv->flags & ORIENTATION_SWAP_XY))) - target->base_orientation = orientation_add(ROT90, target->base_orientation); - if (options_get_bool(machine->options(), OPTION_ROL) || (options_get_bool(machine->options(), OPTION_AUTOROL) && (machine->gamedrv->flags & ORIENTATION_SWAP_XY))) - target->base_orientation = orientation_add(ROT270, target->base_orientation); - - /* flip X/Y */ - if (options_get_bool(machine->options(), OPTION_FLIPX)) - target->base_orientation ^= ORIENTATION_FLIP_X; - if (options_get_bool(machine->options(), OPTION_FLIPY)) - target->base_orientation ^= ORIENTATION_FLIP_Y; - - /* set the orientation and layerconfig equal to the base */ - target->orientation = target->base_orientation; - target->layerconfig = target->base_layerconfig; - - /* allocate a lock for the primitive list */ - for (listnum = 0; listnum < ARRAY_LENGTH(target->primlist); listnum++) - target->primlist[listnum].lock = osd_lock_alloc(); - - /* load the layout files */ - if (load_layout_files(target, layoutfile, flags & RENDER_CREATE_SINGLE_FILE)) - { - render_target_free(target); - return NULL; - } - - /* set the current view to the first one */ - render_target_set_view(target, 0); - - /* make us the UI target if there is none */ - if (ui_target == NULL && !(flags & RENDER_CREATE_HIDDEN)) - render_set_ui_target(target); - return target; -} - - -/*------------------------------------------------- - render_target_free - free memory for a render - target --------------------------------------------------*/ - -void render_target_free(render_target *target) -{ - render_target **curr; - int listnum; - - /* remove us from the list */ - for (curr = &targetlist; *curr != target; curr = &(*curr)->next) ; - *curr = target->next; - - /* free any primitives */ - for (listnum = 0; listnum < ARRAY_LENGTH(target->primlist); listnum++) - { - release_render_list(&target->primlist[listnum]); - osd_lock_free(target->primlist[listnum].lock); - } - - /* free the layout files */ - while (target->filelist != NULL) - { - layout_file *temp = target->filelist; - target->filelist = temp->next; - layout_file_free(temp); - } - - /* free the target itself */ - global_free(target); -} - - -/*------------------------------------------------- - render_target_get_indexed - get a render_target - by index --------------------------------------------------*/ - -render_target *render_target_get_indexed(int index) -{ - render_target *target; - - /* count up the targets until we hit the requested index */ - for (target = targetlist; target != NULL; target = target->next) - if (!(target->flags & RENDER_CREATE_HIDDEN)) - if (index-- == 0) - return target; - return NULL; -} - - -/*------------------------------------------------- - render_target_get_view_name - return the - name of the indexed view, or NULL if it - doesn't exist --------------------------------------------------*/ - -const char *render_target_get_view_name(render_target *target, int viewindex) -{ - layout_file *file; - layout_view *view; - - /* return the name from the indexed view */ - for (file = target->filelist; file != NULL; file = file->next) - for (view = file->viewlist; view != NULL; view = view->next) - if (!(target->flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) - if (viewindex-- == 0) - return view->name; - - return NULL; -} - - -/*------------------------------------------------- - render_target_get_view_screens - return a - bitmask of which screens are visible on a - given view --------------------------------------------------*/ - -UINT32 render_target_get_view_screens(render_target *target, int viewindex) -{ - layout_file *file; - layout_view *view; - - /* return the name from the indexed view */ - for (file = target->filelist; file != NULL; file = file->next) - for (view = file->viewlist; view != NULL; view = view->next) - if (!(target->flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) - if (viewindex-- == 0) - return view->screens; - - return 0; -} - - -/*------------------------------------------------- - render_target_get_bounds - get the bounds and - pixel aspect of a target --------------------------------------------------*/ - -void render_target_get_bounds(render_target *target, INT32 *width, INT32 *height, float *pixel_aspect) -{ - if (width != NULL) - *width = target->width; - if (height != NULL) - *height = target->height; - if (pixel_aspect != NULL) - *pixel_aspect = target->pixel_aspect; -} - - -/*------------------------------------------------- - render_target_set_bounds - set the bounds and - pixel aspect of a target --------------------------------------------------*/ - -void render_target_set_bounds(render_target *target, INT32 width, INT32 height, float pixel_aspect) -{ - target->width = width; - target->height = height; - target->bounds.x0 = target->bounds.y0 = 0; - target->bounds.x1 = (float)width; - target->bounds.y1 = (float)height; - target->pixel_aspect = pixel_aspect; -} - - -/*------------------------------------------------- - render_target_get_max_update_rate - get the - maximum update rate (refresh rate) of a target, - or 0 if no maximum --------------------------------------------------*/ - -float render_target_get_max_update_rate(render_target *target) -{ - return target->max_refresh; -} - - -/*------------------------------------------------- - render_target_set_max_update_rate - set the - maximum update rate (refresh rate) of a target, - or 0 if no maximum --------------------------------------------------*/ - -void render_target_set_max_update_rate(render_target *target, float updates_per_second) -{ - target->max_refresh = updates_per_second; -} - - -/*------------------------------------------------- - render_target_get_orientation - get the - orientation of a target --------------------------------------------------*/ - -int render_target_get_orientation(render_target *target) -{ - return target->orientation; -} - - -/*------------------------------------------------- - render_target_set_orientation - set the - orientation of a target --------------------------------------------------*/ - -void render_target_set_orientation(render_target *target, int orientation) -{ - target->orientation = orientation; -} - - -/*------------------------------------------------- - render_target_get_layer_config - get the - layer config of a target --------------------------------------------------*/ - -int render_target_get_layer_config(render_target *target) -{ - return target->layerconfig; -} - - -/*------------------------------------------------- - render_target_set_layer_config - set the - layer config of a target --------------------------------------------------*/ - -void render_target_set_layer_config(render_target *target, int layerconfig) -{ - target->layerconfig = layerconfig; - layout_view_recompute(target->curview, layerconfig); -} - - -/*------------------------------------------------- - render_target_get_view - return the currently - selected view index --------------------------------------------------*/ - -int render_target_get_view(render_target *target) -{ - layout_file *file; - layout_view *view; - int index = 0; - - /* find the first named match */ - for (file = target->filelist; file != NULL; file = file->next) - for (view = file->viewlist; view != NULL; view = view->next) - if (!(target->flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) - { - if (target->curview == view) - return index; - index++; - } - return 0; -} - - -/*------------------------------------------------- - render_target_set_view - dynamically change - the view for a target --------------------------------------------------*/ - -void render_target_set_view(render_target *target, int viewindex) -{ - layout_file *file; - layout_view *view; - - /* find the first named match */ - for (file = target->filelist; file != NULL; file = file->next) - for (view = file->viewlist; view != NULL; view = view->next) - if (!(target->flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) - if (viewindex-- == 0) - { - target->curview = view; - layout_view_recompute(view, target->layerconfig); - break; - } -} - - -/*------------------------------------------------- - render_target_set_max_texture_size - set the - upper bound on the texture size --------------------------------------------------*/ - -void render_target_set_max_texture_size(render_target *target, int maxwidth, int maxheight) -{ - target->maxtexwidth = maxwidth; - target->maxtexheight = maxheight; -} - - -/*------------------------------------------------- - render_target_compute_visible_area - compute - the visible area for the given target with - the current layout and proposed new parameters --------------------------------------------------*/ - -void render_target_compute_visible_area(render_target *target, INT32 target_width, INT32 target_height, float target_pixel_aspect, int target_orientation, INT32 *visible_width, INT32 *visible_height) -{ - float width, height; - float scale; - - /* constrained case */ - if (target_pixel_aspect != 0.0f) - { - /* start with the aspect ratio of the square pixel layout */ - width = ((target->layerconfig & LAYER_CONFIG_ZOOM_TO_SCREEN) && target->curview->screens > 0) ? target->curview->scraspect : target->curview->aspect; - height = 1.0f; - - /* first apply target orientation */ - if (target_orientation & ORIENTATION_SWAP_XY) - FSWAP(width, height); - - /* apply the target pixel aspect ratio */ - height *= target_pixel_aspect; - - /* based on the height/width ratio of the source and target, compute the scale factor */ - if (width / height > (float)target_width / (float)target_height) - scale = (float)target_width / width; - else - scale = (float)target_height / height; - } - - /* stretch-to-fit case */ - else - { - width = (float)target_width; - height = (float)target_height; - scale = 1.0f; - } - - /* set the final width/height */ - if (visible_width != NULL) - *visible_width = render_round_nearest(width * scale); - if (visible_height != NULL) - *visible_height = render_round_nearest(height * scale); -} - - -/*------------------------------------------------- - render_target_get_minimum_size - get the - "minimum" size of a target, which is the - smallest bounds that will ensure at least - 1 target pixel per source pixel for all - included screens --------------------------------------------------*/ - -void render_target_get_minimum_size(render_target *target, INT32 *minwidth, INT32 *minheight) -{ - float maxxscale = 1.0f, maxyscale = 1.0f; - int screens_considered = 0; - int layer; - - /* scan the current view for all screens */ - for (layer = 0; layer < ITEM_LAYER_MAX; layer++) - { - view_item *item; - - /* iterate over items in the layer */ - for (item = target->curview->itemlist[layer]; item != NULL; item = item->next) - if (item->element == NULL) - { - const screen_device_config *scrconfig = downcast(target->machine->config->m_devicelist.find(SCREEN, item->index)); - screen_device *screendev = downcast(target->machine->m_devicelist.find(scrconfig->tag())); - const rectangle vectorvis = { 0, 639, 0, 479 }; - const rectangle *visarea = NULL; - render_container *container = get_screen_container_by_index(item->index); - render_bounds bounds; - float xscale, yscale; - - /* we may be called very early, before machine->visible_area is initialized; handle that case */ - if (scrconfig->screen_type() == SCREEN_TYPE_VECTOR) - visarea = &vectorvis; - else if (screendev != NULL && screendev->started()) - visarea = &screendev->visible_area(); - else - visarea = &scrconfig->visible_area(); - - /* apply target orientation to the bounds */ - bounds = item->bounds; - apply_orientation(&bounds, target->orientation); - normalize_bounds(&bounds); - - /* based on the orientation of the screen container, check the bitmap */ - if (!(orientation_add(target->orientation, container->orientation) & ORIENTATION_SWAP_XY)) - { - xscale = (float)(visarea->max_x + 1 - visarea->min_x) / (bounds.x1 - bounds.x0); - yscale = (float)(visarea->max_y + 1 - visarea->min_y) / (bounds.y1 - bounds.y0); - } - else - { - xscale = (float)(visarea->max_y + 1 - visarea->min_y) / (bounds.x1 - bounds.x0); - yscale = (float)(visarea->max_x + 1 - visarea->min_x) / (bounds.y1 - bounds.y0); - } - - /* pick the greater */ - maxxscale = MAX(xscale, maxxscale); - maxyscale = MAX(yscale, maxyscale); - screens_considered++; - } - } - - /* if there were no screens considered, pick a nominal default */ - if (screens_considered == 0) - { - maxxscale = 640.0f; - maxyscale = 480.0f; - } - - /* round up */ - if (minwidth != NULL) - *minwidth = render_round_nearest(maxxscale); - if (minheight != NULL) - *minheight = render_round_nearest(maxyscale); -} - - -/*------------------------------------------------- - render_target_get_primitives - return a list - of primitives for a given render target --------------------------------------------------*/ - -const render_primitive_list *render_target_get_primitives(render_target *target) -{ - object_transform root_xform, ui_xform; - int itemcount[ITEM_LAYER_MAX]; - INT32 viswidth, visheight; - int layernum, listnum; - - /* remember the base values if this is the first frame */ - if (target->base_view == NULL) - target->base_view = target->curview; - - /* switch to the next primitive list */ - listnum = target->listindex; - target->listindex = (target->listindex + 1) % ARRAY_LENGTH(target->primlist); - osd_lock_acquire(target->primlist[listnum].lock); - - /* free any previous primitives */ - release_render_list(&target->primlist[listnum]); - - /* compute the visible width/height */ - render_target_compute_visible_area(target, target->width, target->height, target->pixel_aspect, target->orientation, &viswidth, &visheight); - - /* create a root transform for the target */ - root_xform.xoffs = (float) (target->width - viswidth) / 2; - root_xform.yoffs = (float) (target->height - visheight) / 2; - root_xform.xscale = (float) viswidth; - root_xform.yscale = (float) visheight; - root_xform.color.r = root_xform.color.g = root_xform.color.b = root_xform.color.a = 1.0f; - root_xform.orientation = target->orientation; - root_xform.no_center = FALSE; - - /* iterate over layers back-to-front, but only if we're running */ - if (target->machine->phase() >= MACHINE_PHASE_RESET) - for (layernum = 0; layernum < ITEM_LAYER_MAX; layernum++) - { - int blendmode; - int layer = get_layer_and_blendmode(target->curview, layernum, &blendmode); - - if (target->curview->layenabled[layer]) - { - view_item *item; - - /* iterate over items in the layer */ - itemcount[layer] = 0; - for (item = target->curview->itemlist[layer]; item != NULL; item = item->next) - { - object_transform item_xform; - render_bounds bounds; - - /* first apply orientation to the bounds */ - bounds = item->bounds; - apply_orientation(&bounds, root_xform.orientation); - normalize_bounds(&bounds); - - /* apply the transform to the item */ - item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; - item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; - item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; - item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; - item_xform.color.r = item->color.r * root_xform.color.r; - item_xform.color.g = item->color.g * root_xform.color.g; - item_xform.color.b = item->color.b * root_xform.color.b; - item_xform.color.a = item->color.a * root_xform.color.a; - item_xform.orientation = orientation_add(item->orientation, root_xform.orientation); - item_xform.no_center = FALSE; - - /* if there is no associated element, it must be a screen element */ - if (item->element != NULL) - { - int state = 0; - if (item->output_name[0] != 0) - state = output_get_value(item->output_name); - else if (item->input_tag[0] != 0) - { - const input_field_config *field = input_field_by_tag_and_mask(target->machine->m_portlist, item->input_tag, item->input_mask); - if (field != NULL) - state = ((input_port_read_safe(target->machine, item->input_tag, 0) ^ field->defvalue) & item->input_mask) ? 1 : 0; - } - add_element_primitives(target, &target->primlist[listnum], &item_xform, item->element, state, blendmode); - } - else - { - render_container *container = get_screen_container_by_index(item->index); - add_container_primitives(target, &target->primlist[listnum], &item_xform, container, blendmode); - } - - /* keep track of how many items are in the layer */ - itemcount[layer]++; - } - } - } - - /* if we are not in the running stage, draw an outer box */ - else - { - render_primitive *prim; - - prim = alloc_render_primitive(RENDER_PRIMITIVE_QUAD); - set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)target->width, (float)target->height); - set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f); - prim->texture.base = NULL; - prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); - append_render_primitive(&target->primlist[listnum], prim); - - if ((target->width > 1) && (target->height > 1)) - { - prim = alloc_render_primitive(RENDER_PRIMITIVE_QUAD); - set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(target->width - 1), (float)(target->height - 1)); - set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); - prim->texture.base = NULL; - prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); - append_render_primitive(&target->primlist[listnum], prim); - } - } - - /* process the debug containers */ - for (render_container *debug = target->debug_containers; debug != NULL; debug = debug->next) - { - ui_xform.xoffs = 0; - ui_xform.yoffs = 0; - ui_xform.xscale = (float) target->width; - ui_xform.yscale = (float) target->height; - ui_xform.color.r = ui_xform.color.g = ui_xform.color.b = ui_xform.color.a = 1.0f; - ui_xform.color.a = 0.9f; - ui_xform.orientation = target->orientation; - ui_xform.no_center = TRUE; - - /* add UI elements */ - add_container_primitives(target, &target->primlist[listnum], &ui_xform, debug, BLENDMODE_ALPHA); - } - - /* process the UI if we are the UI target */ - if (target == render_get_ui_target()) - { - /* compute the transform for the UI */ - ui_xform.xoffs = 0; - ui_xform.yoffs = 0; - ui_xform.xscale = (float) target->width; - ui_xform.yscale = (float) target->height; - ui_xform.color.r = ui_xform.color.g = ui_xform.color.b = ui_xform.color.a = 1.0f; - ui_xform.orientation = target->orientation; - ui_xform.no_center = FALSE; - - /* add UI elements */ - add_container_primitives(target, &target->primlist[listnum], &ui_xform, ui_container, BLENDMODE_ALPHA); - } - - /* optimize the list before handing it off */ - add_clear_and_optimize_primitive_list(target, &target->primlist[listnum]); - osd_lock_release(target->primlist[listnum].lock); - return &target->primlist[listnum]; -} - - -/*------------------------------------------------- - render_target_map_point_internal - internal - logic for mapping points --------------------------------------------------*/ - -static int render_target_map_point_internal(render_target *target, INT32 target_x, INT32 target_y, render_container *container, float *mapped_x, float *mapped_y, view_item **mapped_item) -{ - float target_fx, target_fy; - view_item *item; - int layernum; - float dummy; - - /* sanity check */ - if (mapped_x == NULL) - mapped_x = &dummy; - if (mapped_y == NULL) - mapped_y = &dummy; - - /* default to point not mapped */ - *mapped_x = -1.0; - *mapped_y = -1.0; - - /* convert target coordinates to float */ - target_fx = (float)target_x / target->width; - target_fy = (float)target_y / target->height; - - /* explicitly check for the UI container */ - if (container != NULL && container == ui_container) - { - /* this hit test went against the UI container */ - if (target_fx >= 0.0 && target_fx < 1.0 && target_fy >= 0.0 && target_fy < 1.0) - { - /* this point was successfully mapped */ - *mapped_x = target_fx; - *mapped_y = target_fy; - *mapped_item = NULL; - return TRUE; - } - return FALSE; - } - - /* loop through each layer */ - for (layernum = 0; layernum < ITEM_LAYER_MAX; layernum++) - { - int layer = get_layer_and_blendmode(target->curview, layernum, NULL); - if (target->curview->layenabled[layer]) - { - /* iterate over items in the layer */ - for (item = target->curview->itemlist[layer]; item != NULL; item = item->next) - { - int checkit; - - /* if we're looking for a particular container, verify that we have the right one */ - if (container != NULL) - checkit = (item->element == NULL && container == get_screen_container_by_index(item->index)); - - /* otherwise, assume we're looking for an input */ - else - checkit = (item->input_tag[0] != 0); - - /* this target is worth looking at; now check the point */ - if (checkit && target_fx >= item->bounds.x0 && target_fx < item->bounds.x1 && target_fy >= item->bounds.y0 && target_fy < item->bounds.y1) - { - /* point successfully mapped */ - *mapped_x = (target_fx - item->bounds.x0) / (item->bounds.x1 - item->bounds.x0); - *mapped_y = (target_fy - item->bounds.y0) / (item->bounds.y1 - item->bounds.y0); - *mapped_item = item; - return TRUE; - } - } - } - } - return FALSE; -} - - -/*------------------------------------------------- - render_target_map_point_container - attempts to - map a point on the specified render_target to - the specified container, if possible --------------------------------------------------*/ - -int render_target_map_point_container(render_target *target, INT32 target_x, INT32 target_y, render_container *container, float *container_x, float *container_y) -{ - view_item *item; - return render_target_map_point_internal(target, target_x, target_y, container, container_x, container_y, &item); -} - - -/*------------------------------------------------- - render_target_map_point_input - attempts to map - a point on the specified render_target to the - specified container, if possible --------------------------------------------------*/ - -int render_target_map_point_input(render_target *target, INT32 target_x, INT32 target_y, const char **input_tag, UINT32 *input_mask, float *input_x, float *input_y) -{ - view_item *item = NULL; - int result; - - result = render_target_map_point_internal(target, target_x, target_y, NULL, input_x, input_y, &item); - if (result && item != NULL) - { - *input_tag = item->input_tag; - *input_mask = item->input_mask; - } - return result; -} - - -/*------------------------------------------------- - load_layout_files - load layout files for a - given render target --------------------------------------------------*/ - -static int load_layout_files(render_target *target, const char *layoutfile, int singlefile) -{ - running_machine *machine = target->machine; - const game_driver *gamedrv = machine->gamedrv; - const machine_config *config = machine->config; - const char *basename = machine->basename(); - layout_file **nextfile = &target->filelist; - const game_driver *cloneof; - - /* if there's an explicit file, load that first */ - if (layoutfile != NULL) - { - *nextfile = layout_file_load(config, basename, layoutfile); - if (*nextfile != NULL) - nextfile = &(*nextfile)->next; - } - - /* if we're only loading this file, we know our final result */ - if (singlefile) - return (nextfile == &target->filelist) ? 1 : 0; - - /* try to load a file based on the driver name */ - *nextfile = layout_file_load(config, basename, gamedrv->name); - if (*nextfile == NULL) - *nextfile = layout_file_load(config, basename, "default"); - if (*nextfile != NULL) - nextfile = &(*nextfile)->next; - - /* if a default view has been specified, use that as a fallback */ - if (gamedrv->default_layout != NULL) - { - *nextfile = layout_file_load(config, NULL, gamedrv->default_layout); - if (*nextfile != NULL) - nextfile = &(*nextfile)->next; - } - if (config->m_default_layout != NULL) - { - *nextfile = layout_file_load(config, NULL, config->m_default_layout); - if (*nextfile != NULL) - nextfile = &(*nextfile)->next; - } - - /* try to load another file based on the parent driver name */ - cloneof = driver_get_clone(gamedrv); - if (cloneof != NULL) - { - *nextfile = layout_file_load(config, cloneof->name, cloneof->name); - if (*nextfile == NULL) - *nextfile = layout_file_load(config, cloneof->name, "default"); - if (*nextfile != NULL) - nextfile = &(*nextfile)->next; - } - - /* now do the built-in layouts for single-screen games */ - if (screen_count(*config) == 1) - { - if (gamedrv->flags & ORIENTATION_SWAP_XY) - *nextfile = layout_file_load(config, NULL, layout_vertical); - else - *nextfile = layout_file_load(config, NULL, layout_horizont); - assert_always(*nextfile != NULL, "Couldn't parse default layout??"); - nextfile = &(*nextfile)->next; - } - return 0; -} - - -/*------------------------------------------------- - release_render_list - release the contents of - a render list --------------------------------------------------*/ - -static void release_render_list(render_primitive_list *list) -{ - /* take the lock */ - osd_lock_acquire(list->lock); - - /* free everything on the list */ - while (list->head != NULL) - { - render_primitive *temp = list->head; - list->head = temp->next; - free_render_primitive(temp); - } - list->nextptr = &list->head; - - /* release all our references */ - while (list->reflist != NULL) - { - render_ref *temp = list->reflist; - list->reflist = temp->next; - free_render_ref(temp); - } - - /* let other people at it again */ - osd_lock_release(list->lock); -} - - -/*------------------------------------------------- - add_container_primitives - add primitives - based on the container --------------------------------------------------*/ - -static void add_container_primitives(render_target *target, render_primitive_list *list, const object_transform *xform, render_container *container, int blendmode) -{ - object_transform container_xform; - render_bounds cliprect; - render_primitive *prim; - container_item *item; - - /* first update the palette for the container, if it is dirty */ - render_container_update_palette(container); - - /* compute the clip rect */ - cliprect.x0 = xform->xoffs; - cliprect.y0 = xform->yoffs; - cliprect.x1 = xform->xoffs + xform->xscale; - cliprect.y1 = xform->yoffs + xform->yscale; - sect_render_bounds(&cliprect, &target->bounds); - - /* compute the container transform */ - container_xform.orientation = orientation_add(container->orientation, xform->orientation); - { - float xscale = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container->yscale : container->xscale; - float yscale = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container->xscale : container->yscale; - float xoffs = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container->yoffset : container->xoffset; - float yoffs = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container->xoffset : container->yoffset; - if (container_xform.orientation & ORIENTATION_FLIP_X) xoffs = -xoffs; - if (container_xform.orientation & ORIENTATION_FLIP_Y) yoffs = -yoffs; - container_xform.xscale = xform->xscale * xscale; - container_xform.yscale = xform->yscale * yscale; - if (xform->no_center) - { - container_xform.xoffs = xform->xscale * (xoffs) + xform->xoffs; - container_xform.yoffs = xform->yscale * (yoffs) + xform->yoffs; - } - else - { - container_xform.xoffs = xform->xscale * (0.5f - 0.5f * xscale + xoffs) + xform->xoffs; - container_xform.yoffs = xform->yscale * (0.5f - 0.5f * yscale + yoffs) + xform->yoffs; - } - container_xform.color = xform->color; - } - - /* iterate over elements */ - for (item = container->itemlist; item != NULL; item = item->next) - { - render_bounds bounds; - int width, height; - int clipped = TRUE; - - /* compute the oriented bounds */ - bounds = item->bounds; - apply_orientation(&bounds, container_xform.orientation); - - /* allocate the primitive and set the transformed bounds/color data */ - prim = alloc_render_primitive(0); - prim->bounds.x0 = render_round_nearest(container_xform.xoffs + bounds.x0 * container_xform.xscale); - prim->bounds.y0 = render_round_nearest(container_xform.yoffs + bounds.y0 * container_xform.yscale); - if (item->internal & INTERNAL_FLAG_CHAR) - { - prim->bounds.x1 = prim->bounds.x0 + render_round_nearest((bounds.x1 - bounds.x0) * container_xform.xscale); - prim->bounds.y1 = prim->bounds.y0 + render_round_nearest((bounds.y1 - bounds.y0) * container_xform.yscale); - } - else - { - prim->bounds.x1 = render_round_nearest(container_xform.xoffs + bounds.x1 * container_xform.xscale); - prim->bounds.y1 = render_round_nearest(container_xform.yoffs + bounds.y1 * container_xform.yscale); - } - - /* compute the color of the primitive */ - prim->color.r = container_xform.color.r * item->color.r; - prim->color.g = container_xform.color.g * item->color.g; - prim->color.b = container_xform.color.b * item->color.b; - prim->color.a = container_xform.color.a * item->color.a; - - /* now switch off the type */ - switch (item->type) - { - case CONTAINER_ITEM_LINE: - /* adjust the color for brightness/contrast/gamma */ - prim->color.a = apply_brightness_contrast_gamma_fp(prim->color.a, container->brightness, container->contrast, container->gamma); - prim->color.r = apply_brightness_contrast_gamma_fp(prim->color.r, container->brightness, container->contrast, container->gamma); - prim->color.g = apply_brightness_contrast_gamma_fp(prim->color.g, container->brightness, container->contrast, container->gamma); - prim->color.b = apply_brightness_contrast_gamma_fp(prim->color.b, container->brightness, container->contrast, container->gamma); - - /* set the line type */ - prim->type = RENDER_PRIMITIVE_LINE; - - /* scale the width by the minimum of X/Y scale factors */ - prim->width = item->width * MIN(container_xform.xscale, container_xform.yscale); - prim->flags = item->flags; - - /* clip the primitive */ - clipped = render_clip_line(&prim->bounds, &cliprect); - break; - - case CONTAINER_ITEM_QUAD: - /* set the quad type */ - prim->type = RENDER_PRIMITIVE_QUAD; - - /* normalize the bounds */ - normalize_bounds(&prim->bounds); - - /* get the scaled bitmap and set the resulting palette */ - if (item->texture != NULL) - { - /* determine the final orientation */ - int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(item->flags), container_xform.orientation); - - /* based on the swap values, get the scaled final texture */ - width = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.y1 - prim->bounds.y0) : (prim->bounds.x1 - prim->bounds.x0); - height = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.x1 - prim->bounds.x0) : (prim->bounds.y1 - prim->bounds.y0); - width = MIN(width, target->maxtexwidth); - height = MIN(height, target->maxtexheight); - if (texture_get_scaled(item->texture, width, height, &prim->texture, &list->reflist)) - { - /* set the palette */ - prim->texture.palette = texture_get_adjusted_palette(item->texture, container); - - /* determine UV coordinates and apply clipping */ - prim->texcoords = oriented_texcoords[finalorient]; - clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); - - /* apply the final orientation from the quad flags and then build up the final flags */ - prim->flags = (item->flags & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | - PRIMFLAG_TEXORIENT(finalorient) | - PRIMFLAG_TEXFORMAT(item->texture->format); - if (blendmode != -1) - prim->flags |= PRIMFLAG_BLENDMODE(blendmode); - else - prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(item->flags)); - } - } - else - { - /* adjust the color for brightness/contrast/gamma */ - prim->color.r = apply_brightness_contrast_gamma_fp(prim->color.r, container->brightness, container->contrast, container->gamma); - prim->color.g = apply_brightness_contrast_gamma_fp(prim->color.g, container->brightness, container->contrast, container->gamma); - prim->color.b = apply_brightness_contrast_gamma_fp(prim->color.b, container->brightness, container->contrast, container->gamma); - - /* no texture -- set the basic flags */ - prim->texture.base = NULL; - prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); - - /* apply clipping */ - clipped = render_clip_quad(&prim->bounds, &cliprect, NULL); - } - break; - } - - /* add to the list or free if we're clipped out */ - if (!clipped) - append_render_primitive(list, prim); - else - free_render_primitive(prim); - } - - /* add the overlay if it exists */ - if (container->overlaytexture != NULL && (target->layerconfig & LAYER_CONFIG_ENABLE_SCREEN_OVERLAY)) - { - INT32 width, height; - - /* allocate a primitive */ - prim = alloc_render_primitive(RENDER_PRIMITIVE_QUAD); - set_render_bounds_wh(&prim->bounds, xform->xoffs, xform->yoffs, xform->xscale, xform->yscale); - prim->color = container_xform.color; - width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0); - height = render_round_nearest(prim->bounds.y1) - render_round_nearest(prim->bounds.y0); - if (texture_get_scaled(container->overlaytexture, - (container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width, - (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, &prim->texture, &list->reflist)) - { - /* determine UV coordinates */ - prim->texcoords = oriented_texcoords[container_xform.orientation]; - - /* set the flags and add it to the list */ - prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | - PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | - PRIMFLAG_TEXFORMAT(container->overlaytexture->format); - append_render_primitive(list, prim); - } - else - free_render_primitive(prim); - } -} - - -/*------------------------------------------------- - add_element_primitives - add the primitive - for an element in the current state --------------------------------------------------*/ - -static void add_element_primitives(render_target *target, render_primitive_list *list, const object_transform *xform, const layout_element *element, int state, int blendmode) -{ - INT32 width = render_round_nearest(xform->xscale); - INT32 height = render_round_nearest(xform->yscale); - render_texture *texture; - render_bounds cliprect; - int clipped = TRUE; - - /* if we're out of range, bail */ - if (state > element->maxstate) - return; - if (state < 0) - state = 0; - - /* get a pointer to the relevant texture */ - texture = element->elemtex[state].texture; - if (texture != NULL) - { - render_primitive *prim = alloc_render_primitive(RENDER_PRIMITIVE_QUAD); - - /* configure the basics */ - prim->color = xform->color; - prim->flags = PRIMFLAG_TEXORIENT(xform->orientation) | PRIMFLAG_BLENDMODE(blendmode) | PRIMFLAG_TEXFORMAT(texture->format); - - /* compute the bounds */ - set_render_bounds_wh(&prim->bounds, render_round_nearest(xform->xoffs), render_round_nearest(xform->yoffs), (float) width, (float) height); - if (xform->orientation & ORIENTATION_SWAP_XY) - ISWAP(width, height); - width = MIN(width, target->maxtexwidth); - height = MIN(height, target->maxtexheight); - - /* get the scaled texture and append it */ - if (texture_get_scaled(texture, width, height, &prim->texture, &list->reflist)) - { - /* compute the clip rect */ - cliprect.x0 = render_round_nearest(xform->xoffs); - cliprect.y0 = render_round_nearest(xform->yoffs); - cliprect.x1 = render_round_nearest(xform->xoffs + xform->xscale); - cliprect.y1 = render_round_nearest(xform->yoffs + xform->yscale); - sect_render_bounds(&cliprect, &target->bounds); - - /* determine UV coordinates and apply clipping */ - prim->texcoords = oriented_texcoords[xform->orientation]; - clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); - } - - /* add to the list or free if we're clipped out */ - if (!clipped) - append_render_primitive(list, prim); - else - free_render_primitive(prim); - } -} - - -/*------------------------------------------------- - init_clear_extents - reset the extents list --------------------------------------------------*/ - -static void init_clear_extents(INT32 width, INT32 height) -{ - clear_extents[0] = -height; - clear_extents[1] = 1; - clear_extents[2] = width; - clear_extent_count = 3; -} - - -/*------------------------------------------------- - remove_clear_extent - remove a quad from the - list of stuff to clear, unless it overlaps - a previous quad --------------------------------------------------*/ - -static int remove_clear_extent(const render_bounds *bounds) -{ - INT32 *max = &clear_extents[MAX_CLEAR_EXTENTS]; - INT32 *last = &clear_extents[clear_extent_count]; - INT32 *ext = &clear_extents[0]; - INT32 boundsx0 = ceil(bounds->x0); - INT32 boundsx1 = floor(bounds->x1); - INT32 boundsy0 = ceil(bounds->y0); - INT32 boundsy1 = floor(bounds->y1); - INT32 y0, y1 = 0; - - /* loop over Y extents */ - while (ext < last) - { - INT32 *linelast; - - /* first entry of each line should always be negative */ - assert(ext[0] < 0.0f); - y0 = y1; - y1 = y0 - ext[0]; - - /* do we intersect this extent? */ - if (boundsy0 < y1 && boundsy1 > y0) - { - INT32 *xext; - INT32 x0, x1 = 0; - - /* split the top */ - if (y0 < boundsy0) - { - int diff = boundsy0 - y0; - - /* make a copy of this extent */ - memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext)); - last += ext[1] + 2; - assert_always(last < max, "Ran out of clear extents!\n"); - - /* split the extent between pieces */ - ext[ext[1] + 2] = -(-ext[0] - diff); - ext[0] = -diff; - - /* advance to the new extent */ - y0 -= ext[0]; - ext += ext[1] + 2; - y1 = y0 - ext[0]; - } - - /* split the bottom */ - if (y1 > boundsy1) - { - int diff = y1 - boundsy1; - - /* make a copy of this extent */ - memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext)); - last += ext[1] + 2; - assert_always(last < max, "Ran out of clear extents!\n"); - - /* split the extent between pieces */ - ext[ext[1] + 2] = -diff; - ext[0] = -(-ext[0] - diff); - - /* recompute y1 */ - y1 = y0 - ext[0]; - } - - /* now remove the X extent */ - linelast = &ext[ext[1] + 2]; - xext = &ext[2]; - while (xext < linelast) - { - x0 = x1; - x1 = x0 + xext[0]; - - /* do we fully intersect this extent? */ - if (boundsx0 >= x0 && boundsx1 <= x1) - { - /* yes; split it */ - memmove(&xext[2], &xext[0], (last - xext) * sizeof(*xext)); - last += 2; - linelast += 2; - assert_always(last < max, "Ran out of clear extents!\n"); - - /* split this extent into three parts */ - xext[0] = boundsx0 - x0; - xext[1] = boundsx1 - boundsx0; - xext[2] = x1 - boundsx1; - - /* recompute x1 */ - x1 = boundsx1; - xext += 2; - } - - /* do we partially intersect this extent? */ - else if (boundsx0 < x1 && boundsx1 > x0) - goto abort; - - /* advance */ - xext++; - - /* do we partially intersect the next extent (which is a non-clear extent)? */ - if (xext < linelast) - { - x0 = x1; - x1 = x0 + xext[0]; - if (boundsx0 < x1 && boundsx1 > x0) - goto abort; - xext++; - } - } - - /* update the count */ - ext[1] = linelast - &ext[2]; - } - - /* advance to the next row */ - ext += 2 + ext[1]; - } - - /* update the total count */ - clear_extent_count = last - &clear_extents[0]; - return TRUE; - -abort: - /* update the total count even on a failure as we may have split extents */ - clear_extent_count = last - &clear_extents[0]; - return FALSE; -} - - -/*------------------------------------------------- - add_clear_extents - add the accumulated - extents as a series of quads to clear --------------------------------------------------*/ - -static void add_clear_extents(render_primitive_list *list) -{ - render_primitive *clearlist = NULL; - render_primitive **clearnext = &clearlist; - INT32 *last = &clear_extents[clear_extent_count]; - INT32 *ext = &clear_extents[0]; - INT32 y0, y1 = 0; - - /* loop over all extents */ - while (ext < last) - { - INT32 *linelast = &ext[ext[1] + 2]; - INT32 *xext = &ext[2]; - INT32 x0, x1 = 0; - - /* first entry should always be negative */ - assert(ext[0] < 0); - y0 = y1; - y1 = y0 - ext[0]; - - /* now remove the X extent */ - while (xext < linelast) - { - x0 = x1; - x1 = x0 + *xext++; - - /* only add entries for non-zero widths */ - if (x1 - x0 > 0) - { - render_primitive *prim = alloc_render_primitive(RENDER_PRIMITIVE_QUAD); - set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); - set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); - prim->texture.base = NULL; - prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); - *clearnext = prim; - clearnext = &prim->next; - } - - /* skip the non-clearing extent */ - x0 = x1; - x1 = x0 + *xext++; - } - - /* advance to the next part */ - ext += 2 + ext[1]; - } - - /* we know that the first primitive in the list will be the global clip */ - /* so we insert the clears immediately after */ - *clearnext = list->head; - list->head = clearlist; -} - - -/*------------------------------------------------- - add_clear_and_optimize_primitive_list - - optimize the primitive list --------------------------------------------------*/ - -static void add_clear_and_optimize_primitive_list(render_target *target, render_primitive_list *list) -{ - render_primitive *prim; - - /* start with the assumption that we need to clear the whole screen */ - init_clear_extents(target->width, target->height); - - /* scan the list until we hit an intersection quad or a line */ - for (prim = list->head; prim != NULL; prim = prim->next) - { - /* switch off the type */ - switch (prim->type) - { - case RENDER_PRIMITIVE_LINE: - goto done; - - case RENDER_PRIMITIVE_QUAD: - { - /* stop when we hit an alpha texture */ - if (PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_PALETTEA16) - goto done; - - /* if this quad can't be cleanly removed from the extents list, we're done */ - if (!remove_clear_extent(&prim->bounds)) - goto done; - - /* change the blendmode on the first primitive to be NONE */ - if (PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_RGB_MULTIPLY) - { - /* RGB multiply will multiply against 0, leaving nothing */ - set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); - prim->texture.base = NULL; - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); - } - else - { - /* for alpha or add modes, we will blend against 0 or add to 0; treat it like none */ - prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); - } - - /* since alpha is disabled, premultiply the RGB values and reset the alpha to 1.0 */ - prim->color.r *= prim->color.a; - prim->color.g *= prim->color.a; - prim->color.b *= prim->color.a; - prim->color.a = 1.0f; - break; - } - } - } - -done: - /* now add the extents to the clear list */ - add_clear_extents(list); -} - - - -/*************************************************************************** - RENDER REFERENCES -***************************************************************************/ - -/*------------------------------------------------- - invalidate_all_render_ref - remove all refs - to a particular reference pointer --------------------------------------------------*/ - -static void invalidate_all_render_ref(void *refptr) -{ - render_target *target; - int listnum; - - /* loop over targets */ - for (target = targetlist; target != NULL; target = target->next) - for (listnum = 0; listnum < ARRAY_LENGTH(target->primlist); listnum++) - { - render_primitive_list *list = &target->primlist[listnum]; - osd_lock_acquire(list->lock); - if (has_render_ref(list->reflist, refptr)) - release_render_list(list); - osd_lock_release(list->lock); - } -} - - - -/*************************************************************************** - RENDER TEXTURES -***************************************************************************/ - -/*------------------------------------------------- - render_texture_alloc - allocate a new texture --------------------------------------------------*/ - -render_texture *render_texture_alloc(texture_scaler_func scaler, void *param) -{ - render_texture *texture; - - /* if nothing on the free list, add some more */ - if (render_texture_free_list == NULL) - { - int texnum; - - /* allocate a new group */ - texture = global_alloc_array_clear(render_texture, TEXTURE_GROUP_SIZE); - - /* add them to the list */ - for (texnum = 0; texnum < TEXTURE_GROUP_SIZE; texnum++) - { - texture[texnum].base = texture; - texture[texnum].next = render_texture_free_list; - render_texture_free_list = &texture[texnum]; - } - } - - /* pull an entry off the free list */ - texture = render_texture_free_list; - render_texture_free_list = texture->next; - - /* fill in the data */ - texture->scaler = scaler; - texture->param = param; - texture->format = TEXFORMAT_ARGB32; - return texture; -} - - -/*------------------------------------------------- - render_texture_free - free an allocated - texture --------------------------------------------------*/ - -void render_texture_free(render_texture *texture) -{ - render_texture *base_save; - int scalenum; - - /* free all scaled versions */ - for (scalenum = 0; scalenum < ARRAY_LENGTH(texture->scaled); scalenum++) - if (texture->scaled[scalenum].bitmap != NULL) - { - invalidate_all_render_ref(texture->scaled[scalenum].bitmap); - global_free(texture->scaled[scalenum].bitmap); - } - - /* invalidate references to the original bitmap as well */ - if (texture->bitmap != NULL) - invalidate_all_render_ref(texture->bitmap); - - /* release palette references */ - if (texture->palette != NULL) - palette_deref(texture->palette); - - /* free any B/C/G lookup tables */ - if (texture->bcglookup != NULL) - global_free(texture->bcglookup); - - /* add ourself back to the free list */ - base_save = texture->base; - memset(texture, 0, sizeof(*texture)); - texture->next = render_texture_free_list; - texture->base = base_save; - render_texture_free_list = texture; -} - - -/*------------------------------------------------- - render_texture_set_bitmap - set a new source - bitmap --------------------------------------------------*/ - -void render_texture_set_bitmap(render_texture *texture, bitmap_t *bitmap, const rectangle *sbounds, int format, palette_t *palette) -{ - int scalenum; - - /* ensure we have a valid palette for palettized modes */ + // ensure we have a valid palette for palettized modes if (format == TEXFORMAT_PALETTE16 || format == TEXFORMAT_PALETTEA16) assert(palette != NULL); - /* invalidate references to the old bitmap */ - if (bitmap != texture->bitmap && texture->bitmap != NULL) - invalidate_all_render_ref(texture->bitmap); + // invalidate references to the old bitmap + if (bitmap != m_bitmap && m_bitmap != NULL) + m_manager->invalidate_all(m_bitmap); - /* if the palette is different, adjust references */ - if (palette != texture->palette) + // if the palette is different, adjust references + if (palette != m_palette) { - if (texture->palette != NULL) - palette_deref(texture->palette); + if (m_palette != NULL) + palette_deref(m_palette); if (palette != NULL) palette_ref(palette); } - /* set the new bitmap/palette */ - texture->bitmap = bitmap; - texture->sbounds.min_x = (sbounds != NULL) ? sbounds->min_x : 0; - texture->sbounds.min_y = (sbounds != NULL) ? sbounds->min_y : 0; - texture->sbounds.max_x = (sbounds != NULL) ? sbounds->max_x : (bitmap != NULL) ? bitmap->width : 1000; - texture->sbounds.max_y = (sbounds != NULL) ? sbounds->max_y : (bitmap != NULL) ? bitmap->height : 1000; - texture->palette = palette; - texture->format = format; + // set the new bitmap/palette + m_bitmap = bitmap; + m_sbounds.min_x = (sbounds != NULL) ? sbounds->min_x : 0; + m_sbounds.min_y = (sbounds != NULL) ? sbounds->min_y : 0; + m_sbounds.max_x = (sbounds != NULL) ? sbounds->max_x : (bitmap != NULL) ? bitmap->width : 1000; + m_sbounds.max_y = (sbounds != NULL) ? sbounds->max_y : (bitmap != NULL) ? bitmap->height : 1000; + m_palette = palette; + m_format = format; - /* invalidate all scaled versions */ - for (scalenum = 0; scalenum < ARRAY_LENGTH(texture->scaled); scalenum++) + // invalidate all scaled versions + for (int scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) { - if (texture->scaled[scalenum].bitmap != NULL) + if (m_scaled[scalenum].bitmap != NULL) { - invalidate_all_render_ref(texture->scaled[scalenum].bitmap); - global_free(texture->scaled[scalenum].bitmap); + m_manager->invalidate_all(m_scaled[scalenum].bitmap); + auto_free(&m_manager->machine(), m_scaled[scalenum].bitmap); } - texture->scaled[scalenum].bitmap = NULL; - texture->scaled[scalenum].seqid = 0; + m_scaled[scalenum].bitmap = NULL; + m_scaled[scalenum].seqid = 0; } } -/*------------------------------------------------- - texture_get_scaled - get a scaled - bitmap (if we can) --------------------------------------------------*/ +//------------------------------------------------- +// hq_scale - generic high quality resampling +// scaler +//------------------------------------------------- -static int texture_get_scaled(render_texture *texture, UINT32 dwidth, UINT32 dheight, render_texinfo *texinfo, render_ref **reflist) +void render_texture::hq_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param) { - UINT8 bpp = (texture->format == TEXFORMAT_PALETTE16 || texture->format == TEXFORMAT_PALETTEA16 || texture->format == TEXFORMAT_RGB15 || texture->format == TEXFORMAT_YUY16) ? 16 : 32; - const rgb_t *palbase = (texture->format == TEXFORMAT_PALETTE16 || texture->format == TEXFORMAT_PALETTEA16) ? palette_entry_list_adjusted(texture->palette) : NULL; - scaled_texture *scaled = NULL; - int swidth, sheight; - int scalenum; + render_color color = { 1.0f, 1.0f, 1.0f, 1.0f }; + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, &source, &sbounds, &color); +} - /* source width/height come from the source bounds */ - swidth = texture->sbounds.max_x - texture->sbounds.min_x; - sheight = texture->sbounds.max_y - texture->sbounds.min_y; - /* ensure height/width are non-zero */ +//------------------------------------------------- +// get_scaled - get a scaled bitmap (if we can) +//------------------------------------------------- + +bool render_texture::get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist) +{ + // source width/height come from the source bounds + int swidth = m_sbounds.max_x - m_sbounds.min_x; + int sheight = m_sbounds.max_y - m_sbounds.min_y; + + // ensure height/width are non-zero if (dwidth < 1) dwidth = 1; if (dheight < 1) dheight = 1; - /* are we scaler-free? if so, just return the source bitmap */ - if (texture->scaler == NULL || (texture->bitmap != NULL && swidth == dwidth && sheight == dheight)) + // are we scaler-free? if so, just return the source bitmap + const rgb_t *palbase = (m_format == TEXFORMAT_PALETTE16 || m_format == TEXFORMAT_PALETTEA16) ? palette_entry_list_adjusted(m_palette) : NULL; + if (m_scaler == NULL || (m_bitmap != NULL && swidth == dwidth && sheight == dheight)) { - /* add a reference and set up the source bitmap */ - add_render_ref(reflist, texture->bitmap); - texinfo->base = (UINT8 *)texture->bitmap->base + (texture->sbounds.min_y * texture->bitmap->rowpixels + texture->sbounds.min_x) * (bpp / 8); - texinfo->rowpixels = texture->bitmap->rowpixels; - texinfo->width = swidth; - texinfo->height = sheight; - texinfo->palette = palbase; - texinfo->seqid = ++texture->curseq; - return TRUE; + // add a reference and set up the source bitmap + primlist.add_reference(m_bitmap); + UINT8 bpp = (m_format == TEXFORMAT_PALETTE16 || m_format == TEXFORMAT_PALETTEA16 || m_format == TEXFORMAT_RGB15 || m_format == TEXFORMAT_YUY16) ? 16 : 32; + texinfo.base = (UINT8 *)m_bitmap->base + (m_sbounds.min_y * m_bitmap->rowpixels + m_sbounds.min_x) * (bpp / 8); + texinfo.rowpixels = m_bitmap->rowpixels; + texinfo.width = swidth; + texinfo.height = sheight; + texinfo.palette = palbase; + texinfo.seqid = ++m_curseq; + return true; } - /* is it a size we already have? */ - for (scalenum = 0; scalenum < ARRAY_LENGTH(texture->scaled); scalenum++) + // is it a size we already have? + scaled_texture *scaled = NULL; + int scalenum; + for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) { - scaled = &texture->scaled[scalenum]; + scaled = &m_scaled[scalenum]; - /* we need a non-NULL bitmap with matching dest size */ + // we need a non-NULL bitmap with matching dest size if (scaled->bitmap != NULL && dwidth == scaled->bitmap->width && dheight == scaled->bitmap->height) break; } - /* did we get one? */ - if (scalenum == ARRAY_LENGTH(texture->scaled)) + // did we get one? + if (scalenum == ARRAY_LENGTH(m_scaled)) { int lowest = -1; - /* didn't find one -- take the entry with the lowest seqnum */ - for (scalenum = 0; scalenum < ARRAY_LENGTH(texture->scaled); scalenum++) - if ((lowest == -1 || texture->scaled[scalenum].seqid < texture->scaled[lowest].seqid) && !has_render_ref(*reflist, texture->scaled[scalenum].bitmap)) + // didn't find one -- take the entry with the lowest seqnum + for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) + if ((lowest == -1 || m_scaled[scalenum].seqid < m_scaled[lowest].seqid) && !primlist.has_reference(m_scaled[scalenum].bitmap)) lowest = scalenum; assert_always(lowest != -1, "Too many live texture instances!"); - /* throw out any existing entries */ - scaled = &texture->scaled[lowest]; + // throw out any existing entries + scaled = &m_scaled[lowest]; if (scaled->bitmap != NULL) { - invalidate_all_render_ref(scaled->bitmap); - global_free(scaled->bitmap); + m_manager->invalidate_all(scaled->bitmap); + auto_free(&m_manager->machine(), scaled->bitmap); } - /* allocate a new bitmap */ - scaled->bitmap = global_alloc(bitmap_t(dwidth, dheight, BITMAP_FORMAT_ARGB32)); - scaled->seqid = ++texture->curseq; + // allocate a new bitmap + scaled->bitmap = auto_alloc(&m_manager->machine(), bitmap_t(dwidth, dheight, BITMAP_FORMAT_ARGB32)); + scaled->seqid = ++m_curseq; - /* let the scaler do the work */ - (*texture->scaler)(scaled->bitmap, texture->bitmap, &texture->sbounds, texture->param); + // let the scaler do the work + (*m_scaler)(*scaled->bitmap, *m_bitmap, m_sbounds, m_param); } - /* finally fill out the new info */ - add_render_ref(reflist, scaled->bitmap); - texinfo->base = scaled->bitmap->base; - texinfo->rowpixels = scaled->bitmap->rowpixels; - texinfo->width = dwidth; - texinfo->height = dheight; - texinfo->palette = palbase; - texinfo->seqid = scaled->seqid; - return TRUE; + // finally fill out the new info + primlist.add_reference(scaled->bitmap); + texinfo.base = scaled->bitmap->base; + texinfo.rowpixels = scaled->bitmap->rowpixels; + texinfo.width = dwidth; + texinfo.height = dheight; + texinfo.palette = palbase; + texinfo.seqid = scaled->seqid; + return true; } -/*------------------------------------------------- - render_texture_hq_scale - generic high quality - resampling scaler --------------------------------------------------*/ +//------------------------------------------------- +// get_adjusted_palette - return the adjusted +// palette for a texture +//------------------------------------------------- -void render_texture_hq_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param) -{ - render_color color = { 1.0f, 1.0f, 1.0f, 1.0f }; - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, source, sbounds, &color); -} - - -/*------------------------------------------------- - texture_get_adjusted_palette - return the - adjusted palette for a texture --------------------------------------------------*/ - -static const rgb_t *texture_get_adjusted_palette(render_texture *texture, render_container *container) +const rgb_t *render_texture::get_adjusted_palette(render_container &container) { const rgb_t *adjusted; int numentries; - int index; - /* override the palette with our adjusted palette */ - switch (texture->format) + // override the palette with our adjusted palette + switch (m_format) { case TEXFORMAT_PALETTE16: case TEXFORMAT_PALETTEA16: - /* if no adjustment necessary, return the raw palette */ - assert(texture->palette != NULL); - adjusted = palette_entry_list_adjusted(texture->palette); - if (container->brightness == 1.0f && container->contrast == 1.0f && container->gamma == 1.0f) + // if no adjustment necessary, return the raw palette + assert(m_palette != NULL); + adjusted = palette_entry_list_adjusted(m_palette); + if (!container.has_brightness_contrast_gamma_changes()) return adjusted; - /* if this is the machine palette, return our precomputed adjusted palette */ - if (container->palclient != NULL && palette_client_get_palette(container->palclient) == texture->palette) - return container->bcglookup; + // if this is the machine palette, return our precomputed adjusted palette + adjusted = container.bcg_lookup_table(m_format, m_palette); + if (adjusted != NULL) + return adjusted; - /* otherwise, ensure we have memory allocated and compute the adjusted result ourself */ - numentries = palette_get_num_colors(texture->palette) * palette_get_num_groups(texture->palette); - if (texture->bcglookup == NULL || texture->bcglookup_entries < numentries) + // otherwise, ensure we have memory allocated and compute the adjusted result ourself + numentries = palette_get_num_colors(m_palette) * palette_get_num_groups(m_palette); + if (m_bcglookup == NULL || m_bcglookup_entries < numentries) { - rgb_t *newlookup = global_alloc_array(rgb_t, numentries); - memcpy(newlookup, texture->bcglookup, texture->bcglookup_entries * sizeof(rgb_t)); - global_free(texture->bcglookup); - texture->bcglookup = newlookup; - texture->bcglookup_entries = numentries; + rgb_t *newlookup = auto_alloc_array(&m_manager->machine(), rgb_t, numentries); + memcpy(newlookup, m_bcglookup, m_bcglookup_entries * sizeof(rgb_t)); + auto_free(&m_manager->machine(), m_bcglookup); + m_bcglookup = newlookup; + m_bcglookup_entries = numentries; } - for (index = 0; index < numentries; index++) + for (int index = 0; index < numentries; index++) { - UINT8 r = apply_brightness_contrast_gamma(RGB_RED(adjusted[index]), container->brightness, container->contrast, container->gamma); - UINT8 g = apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index]), container->brightness, container->contrast, container->gamma); - UINT8 b = apply_brightness_contrast_gamma(RGB_BLUE(adjusted[index]), container->brightness, container->contrast, container->gamma); - texture->bcglookup[index] = MAKE_ARGB(RGB_ALPHA(adjusted[index]), r, g, b); + UINT8 r = container.apply_brightness_contrast_gamma(RGB_RED(adjusted[index])); + UINT8 g = container.apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index])); + UINT8 b = container.apply_brightness_contrast_gamma(RGB_BLUE(adjusted[index])); + m_bcglookup[index] = MAKE_ARGB(RGB_ALPHA(adjusted[index]), r, g, b); } - return texture->bcglookup; + return m_bcglookup; case TEXFORMAT_RGB15: - /* if no adjustment necessary, return NULL */ - if (container->brightness == 1.0f && container->contrast == 1.0f && container->gamma == 1.0f && texture->palette == NULL) + // if no adjustment necessary, return NULL + if (!container.has_brightness_contrast_gamma_changes() && m_palette == NULL) return NULL; - /* if no palette, return the standard lookups */ - if (texture->palette == NULL) - return container->bcglookup32; + // if no palette, return the standard lookups + if (m_palette == NULL) + return container.bcg_lookup_table(m_format); - /* otherwise, ensure we have memory allocated and compute the adjusted result ourself */ - assert(palette_get_num_colors(texture->palette) == 32); - adjusted = palette_entry_list_adjusted(texture->palette); - if (texture->bcglookup == NULL || texture->bcglookup_entries < 4 * 32) + // otherwise, ensure we have memory allocated and compute the adjusted result ourself + assert(palette_get_num_colors(m_palette) == 32); + adjusted = palette_entry_list_adjusted(m_palette); + if (m_bcglookup == NULL || m_bcglookup_entries < 4 * 32) { - rgb_t *newlookup = global_alloc_array(rgb_t, 4 * 32); - memcpy(newlookup, texture->bcglookup, texture->bcglookup_entries * sizeof(rgb_t)); - global_free(texture->bcglookup); - texture->bcglookup = newlookup; - texture->bcglookup_entries = 4 * 32; + rgb_t *newlookup = auto_alloc_array(&m_manager->machine(), rgb_t, 4 * 32); + memcpy(newlookup, m_bcglookup, m_bcglookup_entries * sizeof(rgb_t)); + auto_free(&m_manager->machine(), m_bcglookup); + m_bcglookup = newlookup; + m_bcglookup_entries = 4 * 32; } - /* otherwise, return the 32-entry BCG lookups */ - for (index = 0; index < 32; index++) + // otherwise, return the 32-entry BCG lookups + for (int index = 0; index < 32; index++) { - UINT8 val = apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index]), container->brightness, container->contrast, container->gamma); - texture->bcglookup[0x00 + index] = val << 0; - texture->bcglookup[0x20 + index] = val << 8; - texture->bcglookup[0x40 + index] = val << 16; - texture->bcglookup[0x60 + index] = val << 24; + UINT8 val = container.apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index])); + m_bcglookup[0x00 + index] = val << 0; + m_bcglookup[0x20 + index] = val << 8; + m_bcglookup[0x40 + index] = val << 16; + m_bcglookup[0x60 + index] = val << 24; } - return texture->bcglookup; + return m_bcglookup; case TEXFORMAT_RGB32: case TEXFORMAT_ARGB32: case TEXFORMAT_YUY16: - /* if no adjustment necessary, return NULL */ - if (container->brightness == 1.0f && container->contrast == 1.0f && container->gamma == 1.0f && texture->palette == NULL) + // if no adjustment necessary, return NULL + if (!container.has_brightness_contrast_gamma_changes() && m_palette == NULL) return NULL; - /* if no palette, return the standard lookups */ - if (texture->palette == NULL) - return container->bcglookup256; + // if no palette, return the standard lookups + if (m_palette == NULL) + return container.bcg_lookup_table(m_format); - /* otherwise, ensure we have memory allocated and compute the adjusted result ourself */ - assert(palette_get_num_colors(texture->palette) == 256); - adjusted = palette_entry_list_adjusted(texture->palette); - if (texture->bcglookup == NULL || texture->bcglookup_entries < 4 * 256) + // otherwise, ensure we have memory allocated and compute the adjusted result ourself + assert(palette_get_num_colors(m_palette) == 256); + adjusted = palette_entry_list_adjusted(m_palette); + if (m_bcglookup == NULL || m_bcglookup_entries < 4 * 256) { - rgb_t *newlookup = global_alloc_array(rgb_t, 4 * 256); - memcpy(newlookup, texture->bcglookup, texture->bcglookup_entries * sizeof(rgb_t)); - global_free(texture->bcglookup); - texture->bcglookup = newlookup; - texture->bcglookup_entries = 4 * 256; + rgb_t *newlookup = auto_alloc_array(&m_manager->machine(), rgb_t, 4 * 256); + memcpy(newlookup, m_bcglookup, m_bcglookup_entries * sizeof(rgb_t)); + auto_free(&m_manager->machine(), m_bcglookup); + m_bcglookup = newlookup; + m_bcglookup_entries = 4 * 256; } - /* otherwise, return the 32-entry BCG lookups */ - for (index = 0; index < 256; index++) + // otherwise, return the 32-entry BCG lookups + for (int index = 0; index < 256; index++) { - UINT8 val = apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index]), container->brightness, container->contrast, container->gamma); - texture->bcglookup[0x000 + index] = val << 0; - texture->bcglookup[0x100 + index] = val << 8; - texture->bcglookup[0x200 + index] = val << 16; - texture->bcglookup[0x300 + index] = val << 24; + UINT8 val = container.apply_brightness_contrast_gamma(RGB_GREEN(adjusted[index])); + m_bcglookup[0x000 + index] = val << 0; + m_bcglookup[0x100 + index] = val << 8; + m_bcglookup[0x200 + index] = val << 16; + m_bcglookup[0x300 + index] = val << 24; } - return texture->bcglookup; + return m_bcglookup; default: assert(FALSE); @@ -2790,450 +665,2072 @@ static const rgb_t *texture_get_adjusted_palette(render_texture *texture, render -/*************************************************************************** - RENDER CONTAINERS -***************************************************************************/ +//************************************************************************** +// RENDER CONTAINER +//************************************************************************** -/*------------------------------------------------- - render_container_alloc - allocate a render - container --------------------------------------------------*/ +//------------------------------------------------- +// render_container - constructor +//------------------------------------------------- -static render_container *render_container_alloc(running_machine *machine) +render_container::render_container(render_manager &manager, screen_device *screen) + : m_next(NULL), + m_manager(manager), + m_itemlist(manager.machine().m_respool), + m_item_allocator(manager.machine().m_respool), + m_screen(screen), + m_overlaybitmap(NULL), + m_overlaytexture(NULL), + m_palclient(NULL) { - render_container *container; - int color; + // all palette entries are opaque by default + for (int color = 0; color < ARRAY_LENGTH(m_bcglookup); color++) + m_bcglookup[color] = MAKE_ARGB(0xff,0x00,0x00,0x00); - /* allocate and clear memory */ - container = global_alloc_clear(render_container); + // make sure it is empty + empty(); - /* default values */ - container->brightness = 1.0f; - container->contrast = 1.0f; - container->gamma = 1.0f; - container->xscale = 1.0f; - container->yscale = 1.0f; - - /* all palette entries are opaque by default */ - for (color = 0; color < ARRAY_LENGTH(container->bcglookup); color++) - container->bcglookup[color] = MAKE_ARGB(0xff,0x00,0x00,0x00); - - /* make sure it is empty */ - render_container_empty(container); - - /* allocate a client to the main palette */ - if (machine->palette != NULL) - container->palclient = palette_client_alloc(machine->palette); - render_container_recompute_lookups(container); - return container; -} - - -/*------------------------------------------------- - render_container_free - free a render - container --------------------------------------------------*/ - -static void render_container_free(render_container *container) -{ - /* free all the container items */ - render_container_empty(container); - - /* free the overlay texture */ - if (container->overlaytexture != NULL) - render_texture_free(container->overlaytexture); - - /* release our palette client */ - if (container->palclient != NULL) - palette_client_free(container->palclient); - - /* free the container itself */ - global_free(container); -} - - -/*------------------------------------------------- - render_container_empty - empty a container - in preparation for new stuff --------------------------------------------------*/ - -void render_container_empty(render_container *container) -{ - /* free all the container items */ - while (container->itemlist != NULL) + // if we have a screen, read and apply the options + if (screen != NULL) { - container_item *temp = container->itemlist; - container->itemlist = temp->next; - free_container_item(temp); + // set the initial orientation and brightness/contrast/gamma + m_user.m_orientation = manager.machine().gamedrv->flags & ORIENTATION_MASK; + m_user.m_brightness = options_get_float(manager.machine().options(), OPTION_BRIGHTNESS); + m_user.m_contrast = options_get_float(manager.machine().options(), OPTION_CONTRAST); + m_user.m_gamma = options_get_float(manager.machine().options(), OPTION_GAMMA); } - /* reset our newly-added pointer */ - container->nextitem = &container->itemlist; + // allocate a client to the main palette + if (manager.machine().palette != NULL) + m_palclient = palette_client_alloc(manager.machine().palette); + recompute_lookups(); } -/*------------------------------------------------- - render_container_is_empty - return true if - a container has nothing in it --------------------------------------------------*/ +//------------------------------------------------- +// ~render_container - destructor +//------------------------------------------------- -int render_container_is_empty(render_container *container) +render_container::~render_container() { - return (container->itemlist == NULL); + // free all the container items + empty(); + + // free the overlay texture + m_manager.texture_free(m_overlaytexture); + + // release our palette client + if (m_palclient != NULL) + palette_client_free(m_palclient); } -/*------------------------------------------------- - render_container_get_user_settings - get the - current user settings for a container --------------------------------------------------*/ +//------------------------------------------------- +// set_overlay - set the overlay bitmap for the +// container +//------------------------------------------------- -void render_container_get_user_settings(render_container *container, render_container_user_settings *settings) +void render_container::set_overlay(bitmap_t *bitmap) { - settings->orientation = container->orientation; - settings->brightness = container->brightness; - settings->contrast = container->contrast; - settings->gamma = container->gamma; - settings->xscale = container->xscale; - settings->yscale = container->yscale; - settings->xoffset = container->xoffset; - settings->yoffset = container->yoffset; -} + // free any existing texture + m_manager.texture_free(m_overlaytexture); - -/*------------------------------------------------- - render_container_set_user_settings - set the - current user settings for a container --------------------------------------------------*/ - -void render_container_set_user_settings(render_container *container, const render_container_user_settings *settings) -{ - container->orientation = settings->orientation; - container->brightness = settings->brightness; - container->contrast = settings->contrast; - container->gamma = settings->gamma; - container->xscale = settings->xscale; - container->yscale = settings->yscale; - container->xoffset = settings->xoffset; - container->yoffset = settings->yoffset; - render_container_recompute_lookups(container); -} - - -/*------------------------------------------------- - render_container_set_overlay - set the - overlay bitmap for the container --------------------------------------------------*/ - -void render_container_set_overlay(render_container *container, bitmap_t *bitmap) -{ - /* free any existing texture */ - if (container->overlaytexture != NULL) - render_texture_free(container->overlaytexture); - - /* set the new data and allocate the texture */ - container->overlaybitmap = bitmap; - if (container->overlaybitmap != NULL) + // set the new data and allocate the texture + m_overlaybitmap = bitmap; + if (m_overlaybitmap != NULL) { - container->overlaytexture = render_texture_alloc(render_container_overlay_scale, NULL); - render_texture_set_bitmap(container->overlaytexture, bitmap, NULL, TEXFORMAT_ARGB32, NULL); + m_overlaytexture = m_manager.texture_alloc(render_container::overlay_scale); + m_overlaytexture->set_bitmap(bitmap, NULL, TEXFORMAT_ARGB32); } } -/*------------------------------------------------- - render_container_get_ui - return a pointer - to the UI container --------------------------------------------------*/ +//------------------------------------------------- +// set_user_settings - set the current user +// settings for a container +//------------------------------------------------- -render_container *render_container_get_ui(void) +void render_container::set_user_settings(const user_settings &settings) { - return ui_container; + m_user = settings; + recompute_lookups(); } -/*------------------------------------------------- - render_container_get_screen - return a pointer - to the screen container for this device --------------------------------------------------*/ +//------------------------------------------------- +// add_line - add a line item to this container +//------------------------------------------------- -render_container *render_container_get_screen(screen_device *screen) +void render_container::add_line(float x0, float y0, float x1, float y1, float width, rgb_t argb, UINT32 flags) { - render_container *container; - - assert(screen != NULL); - - /* get the container for the screen device */ - for (container = screen_container_list; container != NULL; container = container->next) - if (container->screen == screen) - break; - - assert(container != NULL); - - return container; + item &newitem = add_generic(CONTAINER_ITEM_LINE, x0, y0, x1, y1, argb); + newitem.m_width = width; + newitem.m_flags = flags; } -/*------------------------------------------------- - render_container_item_add_generic - add a - generic item to a container --------------------------------------------------*/ +//------------------------------------------------- +// add_quad - add a quad item to this container +//------------------------------------------------- -static container_item *render_container_item_add_generic(render_container *container, UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb) +void render_container::add_quad(float x0, float y0, float x1, float y1, rgb_t argb, render_texture *texture, UINT32 flags) { - container_item *item = alloc_container_item(); - - assert(container != NULL); - - /* copy the data into the new item */ - item->type = type; - item->bounds.x0 = x0; - item->bounds.y0 = y0; - item->bounds.x1 = x1; - item->bounds.y1 = y1; - item->color.r = (float)RGB_RED(argb) * (1.0f / 255.0f); - item->color.g = (float)RGB_GREEN(argb) * (1.0f / 255.0f); - item->color.b = (float)RGB_BLUE(argb) * (1.0f / 255.0f); - item->color.a = (float)RGB_ALPHA(argb) * (1.0f / 255.0f); - - /* add the item to the container */ - *container->nextitem = item; - container->nextitem = &item->next; - - return item; + item &newitem = add_generic(CONTAINER_ITEM_QUAD, x0, y0, x1, y1, argb); + newitem.m_texture = texture; + newitem.m_flags = flags; } -/*------------------------------------------------- - render_container_add_line - add a line item - to the specified container --------------------------------------------------*/ +//------------------------------------------------- +// add_char - add a char item to this container +//------------------------------------------------- -void render_container_add_line(render_container *container, float x0, float y0, float x1, float y1, float width, rgb_t argb, UINT32 flags) +void render_container::add_char(float x0, float y0, float height, float aspect, rgb_t argb, render_font &font, UINT16 ch) { - container_item *item = render_container_item_add_generic(container, CONTAINER_ITEM_LINE, x0, y0, x1, y1, argb); - item->width = width; - item->flags = flags; -} - - -/*------------------------------------------------- - render_container_add_quad - add a quad item - to the specified container --------------------------------------------------*/ - -void render_container_add_quad(render_container *container, float x0, float y0, float x1, float y1, rgb_t argb, render_texture *texture, UINT32 flags) -{ - container_item *item = render_container_item_add_generic(container, CONTAINER_ITEM_QUAD, x0, y0, x1, y1, argb); - item->texture = texture; - item->flags = flags; -} - - -/*------------------------------------------------- - render_container_add_char - add a char item - to the specified container --------------------------------------------------*/ - -void render_container_add_char(render_container *container, float x0, float y0, float height, float aspect, rgb_t argb, render_font *font, UINT16 ch) -{ - render_texture *texture; + // compute the bounds of the character cell and get the texture render_bounds bounds; - container_item *item; - - /* compute the bounds of the character cell and get the texture */ bounds.x0 = x0; bounds.y0 = y0; - texture = render_font_get_char_texture_and_bounds(font, height, aspect, ch, &bounds); + render_texture *texture = render_font_get_char_texture_and_bounds(&font, height, aspect, ch, &bounds); - /* add it like a quad */ - item = render_container_item_add_generic(container, CONTAINER_ITEM_QUAD, bounds.x0, bounds.y0, bounds.x1, bounds.y1, argb); - item->texture = texture; - item->flags = PRIMFLAG_TEXORIENT(ROT0) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); - item->internal = INTERNAL_FLAG_CHAR; + // add it like a quad + item &newitem = add_generic(CONTAINER_ITEM_QUAD, bounds.x0, bounds.y0, bounds.x1, bounds.y1, argb); + newitem.m_texture = texture; + newitem.m_flags = PRIMFLAG_TEXORIENT(ROT0) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + newitem.m_internal = INTERNAL_FLAG_CHAR; } -/*------------------------------------------------- - render_container_overlay_scale - scaler for - an overlay --------------------------------------------------*/ +//------------------------------------------------- +// apply_brightness_contrast_gamma - apply the +// container's brightess, contrast, and gamma to +// an 8-bit value +//------------------------------------------------- -static void render_container_overlay_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param) +UINT8 render_container::apply_brightness_contrast_gamma(UINT8 value) { - int x, y; + return ::apply_brightness_contrast_gamma(value, m_user.m_brightness, m_user.m_contrast, m_user.m_gamma); +} - /* simply replicate the source bitmap over the target */ - for (y = 0; y < dest->height; y++) + +//------------------------------------------------- +// apply_brightness_contrast_gamma_fp - apply the +// container's brightess, contrast, and gamma to +// a floating-point value +//------------------------------------------------- + +float render_container::apply_brightness_contrast_gamma_fp(float value) +{ + return ::apply_brightness_contrast_gamma_fp(value, m_user.m_brightness, m_user.m_contrast, m_user.m_gamma); +} + + +//------------------------------------------------- +// bcg_lookup_table - return the appropriate +// brightness/contrast/gamma lookup table for a +// given texture mode +//------------------------------------------------- + +const rgb_t *render_container::bcg_lookup_table(int texformat, palette_t *palette) +{ + switch (texformat) { - UINT32 *src = (UINT32 *)source->base + (y % source->height) * source->rowpixels; - UINT32 *dst = (UINT32 *)dest->base + y * dest->rowpixels; + case TEXFORMAT_PALETTE16: + case TEXFORMAT_PALETTEA16: + return (palette != NULL && palette == palette_client_get_palette(m_palclient)) ? m_bcglookup : NULL; + + case TEXFORMAT_RGB15: + return m_bcglookup32; + + case TEXFORMAT_RGB32: + case TEXFORMAT_ARGB32: + case TEXFORMAT_YUY16: + return m_bcglookup256; + + default: + return NULL; + } +} + + +//------------------------------------------------- +// overlay_scale - scaler for an overlay +//------------------------------------------------- + +void render_container::overlay_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param) +{ + // simply replicate the source bitmap over the target + for (int y = 0; y < dest.height; y++) + { + UINT32 *src = (UINT32 *)source.base + (y % source.height) * source.rowpixels; + UINT32 *dst = (UINT32 *)dest.base + y * dest.rowpixels; int sx = 0; - /* loop over columns */ - for (x = 0; x < dest->width; x++) + // loop over columns + for (int x = 0; x < dest.width; x++) { *dst++ = src[sx++]; - if (sx >= source->width) + if (sx >= source.width) sx = 0; } } } -/*------------------------------------------------- - render_container_recompute_lookups - recompute - the lookup table for the render container --------------------------------------------------*/ +//------------------------------------------------- +// add_generic - add a generic item to a +// container +//------------------------------------------------- -static void render_container_recompute_lookups(render_container *container) +render_container::item &render_container::add_generic(UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb) { - int i; + item *newitem = m_item_allocator.alloc(); - /* recompute the 256 entry lookup table */ - for (i = 0; i < 0x100; i++) + // copy the data into the new item + newitem->m_type = type; + newitem->m_bounds.x0 = x0; + newitem->m_bounds.y0 = y0; + newitem->m_bounds.x1 = x1; + newitem->m_bounds.y1 = y1; + newitem->m_color.r = (float)RGB_RED(argb) * (1.0f / 255.0f); + newitem->m_color.g = (float)RGB_GREEN(argb) * (1.0f / 255.0f); + newitem->m_color.b = (float)RGB_BLUE(argb) * (1.0f / 255.0f); + newitem->m_color.a = (float)RGB_ALPHA(argb) * (1.0f / 255.0f); + newitem->m_flags = 0; + newitem->m_internal = 0; + newitem->m_width = 0; + newitem->m_texture = NULL; + + // add the item to the container + return m_itemlist.append(*newitem); +} + + +//------------------------------------------------- +// recompute_lookups - recompute the lookup table +// for the render container +//------------------------------------------------- + +void render_container::recompute_lookups() +{ + // recompute the 256 entry lookup table + for (int i = 0; i < 0x100; i++) { - UINT8 adjustedval = apply_brightness_contrast_gamma(i, container->brightness, container->contrast, container->gamma); - container->bcglookup256[i + 0x000] = adjustedval << 0; - container->bcglookup256[i + 0x100] = adjustedval << 8; - container->bcglookup256[i + 0x200] = adjustedval << 16; - container->bcglookup256[i + 0x300] = adjustedval << 24; + UINT8 adjustedval = apply_brightness_contrast_gamma(i); + m_bcglookup256[i + 0x000] = adjustedval << 0; + m_bcglookup256[i + 0x100] = adjustedval << 8; + m_bcglookup256[i + 0x200] = adjustedval << 16; + m_bcglookup256[i + 0x300] = adjustedval << 24; } - /* recompute the 32 entry lookup table */ - for (i = 0; i < 0x20; i++) + // recompute the 32 entry lookup table + for (int i = 0; i < 0x20; i++) { - UINT8 adjustedval = apply_brightness_contrast_gamma(pal5bit(i), container->brightness, container->contrast, container->gamma); - container->bcglookup32[i + 0x000] = adjustedval << 0; - container->bcglookup32[i + 0x020] = adjustedval << 8; - container->bcglookup32[i + 0x040] = adjustedval << 16; - container->bcglookup32[i + 0x060] = adjustedval << 24; + UINT8 adjustedval = apply_brightness_contrast_gamma(pal5bit(i)); + m_bcglookup32[i + 0x000] = adjustedval << 0; + m_bcglookup32[i + 0x020] = adjustedval << 8; + m_bcglookup32[i + 0x040] = adjustedval << 16; + m_bcglookup32[i + 0x060] = adjustedval << 24; } - /* recompute the palette entries */ - if (container->palclient != NULL) + // recompute the palette entries + if (m_palclient != NULL) { - palette_t *palette = palette_client_get_palette(container->palclient); + palette_t *palette = palette_client_get_palette(m_palclient); const pen_t *adjusted_palette = palette_entry_list_adjusted(palette); int colors = palette_get_num_colors(palette) * palette_get_num_groups(palette); - for (i = 0; i < colors; i++) + for (int i = 0; i < colors; i++) { pen_t newval = adjusted_palette[i]; - container->bcglookup[i] = (newval & 0xff000000) | - container->bcglookup256[0x200 + RGB_RED(newval)] | - container->bcglookup256[0x100 + RGB_GREEN(newval)] | - container->bcglookup256[0x000 + RGB_BLUE(newval)]; + m_bcglookup[i] = (newval & 0xff000000) | + m_bcglookup256[0x200 + RGB_RED(newval)] | + m_bcglookup256[0x100 + RGB_GREEN(newval)] | + m_bcglookup256[0x000 + RGB_BLUE(newval)]; } } } -/*------------------------------------------------- - render_container_update_palette - update - any dirty palette entries --------------------------------------------------*/ +//------------------------------------------------- +// update_palette - update any dirty palette +// entries +//------------------------------------------------- -static void render_container_update_palette(render_container *container) +void render_container::update_palette() { - UINT32 mindirty, maxdirty; - const UINT32 *dirty; - - /* skip if no client */ - if (container->palclient == NULL) + // skip if no client + if (m_palclient == NULL) return; - /* get the dirty list */ - dirty = palette_client_get_dirty_list(container->palclient, &mindirty, &maxdirty); + // get the dirty list + UINT32 mindirty, maxdirty; + const UINT32 *dirty = palette_client_get_dirty_list(m_palclient, &mindirty, &maxdirty); - /* iterate over dirty items and update them */ + // iterate over dirty items and update them if (dirty != NULL) { - palette_t *palette = palette_client_get_palette(container->palclient); + palette_t *palette = palette_client_get_palette(m_palclient); const pen_t *adjusted_palette = palette_entry_list_adjusted(palette); - UINT32 entry32, entry; - /* loop over chunks of 32 entries, since we can quickly examine 32 at a time */ - for (entry32 = mindirty / 32; entry32 <= maxdirty / 32; entry32++) + // loop over chunks of 32 entries, since we can quickly examine 32 at a time + for (UINT32 entry32 = mindirty / 32; entry32 <= maxdirty / 32; entry32++) { UINT32 dirtybits = dirty[entry32]; if (dirtybits != 0) - /* this chunk of 32 has dirty entries; fix them up */ - for (entry = 0; entry < 32; entry++) + // this chunk of 32 has dirty entries; fix them up + for (UINT32 entry = 0; entry < 32; entry++) if (dirtybits & (1 << entry)) { UINT32 finalentry = entry32 * 32 + entry; rgb_t newval = adjusted_palette[finalentry]; - container->bcglookup[finalentry] = (newval & 0xff000000) | - container->bcglookup256[0x200 + RGB_RED(newval)] | - container->bcglookup256[0x100 + RGB_GREEN(newval)] | - container->bcglookup256[0x000 + RGB_BLUE(newval)]; + m_bcglookup[finalentry] = (newval & 0xff000000) | + m_bcglookup256[0x200 + RGB_RED(newval)] | + m_bcglookup256[0x100 + RGB_GREEN(newval)] | + m_bcglookup256[0x000 + RGB_BLUE(newval)]; } } } } -render_container *render_debug_alloc(render_target *target) +//------------------------------------------------- +// user_settings - constructor +//------------------------------------------------- + +render_container::user_settings::user_settings() + : m_orientation(0), + m_brightness(1.0f), + m_contrast(1.0f), + m_gamma(1.0f), + m_xscale(1.0f), + m_yscale(1.0f), + m_xoffset(0.0f), + m_yoffset(0.0f) { - render_container *container = render_container_alloc(target->machine); +} - container->next = target->debug_containers; - target->debug_containers = container; + +//************************************************************************** +// RENDER TARGET +//************************************************************************** + +//------------------------------------------------- +// render_target - constructor +//------------------------------------------------- + +render_target::render_target(render_manager &manager, const char *layoutfile, UINT32 flags) + : m_next(NULL), + m_manager(manager), + m_curview(NULL), + m_filelist(NULL), + m_flags(flags), + m_listindex(0), + m_width(640), + m_height(480), + m_pixel_aspect(0.0f), + m_max_refresh(0), + m_orientation(0), + m_layerconfig(LAYER_CONFIG_DEFAULT), + m_base_view(NULL), + m_base_orientation(ROT0), + m_base_layerconfig(LAYER_CONFIG_DEFAULT), + m_maxtexwidth(65536), + m_maxtexheight(65536), + m_debug_containers(manager.machine().m_respool) +{ + // determine the base layer configuration based on options + if (!options_get_bool(manager.machine().options(), OPTION_USE_BACKDROPS)) m_base_layerconfig &= ~LAYER_CONFIG_ENABLE_BACKDROP; + if (!options_get_bool(manager.machine().options(), OPTION_USE_OVERLAYS)) m_base_layerconfig &= ~LAYER_CONFIG_ENABLE_OVERLAY; + if (!options_get_bool(manager.machine().options(), OPTION_USE_BEZELS)) m_base_layerconfig &= ~LAYER_CONFIG_ENABLE_BEZEL; + if (options_get_bool(manager.machine().options(), OPTION_ARTWORK_CROP)) m_base_layerconfig |= LAYER_CONFIG_ZOOM_TO_SCREEN; + + // determine the base orientation based on options + m_orientation = ROT0; + if (!options_get_bool(manager.machine().options(), OPTION_ROTATE)) + m_base_orientation = orientation_reverse(manager.machine().gamedrv->flags & ORIENTATION_MASK); + + // rotate left/right + if (options_get_bool(manager.machine().options(), OPTION_ROR) || (options_get_bool(manager.machine().options(), OPTION_AUTOROR) && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) + m_base_orientation = orientation_add(ROT90, m_base_orientation); + if (options_get_bool(manager.machine().options(), OPTION_ROL) || (options_get_bool(manager.machine().options(), OPTION_AUTOROL) && (manager.machine().gamedrv->flags & ORIENTATION_SWAP_XY))) + m_base_orientation = orientation_add(ROT270, m_base_orientation); + + // flip X/Y + if (options_get_bool(manager.machine().options(), OPTION_FLIPX)) + m_base_orientation ^= ORIENTATION_FLIP_X; + if (options_get_bool(manager.machine().options(), OPTION_FLIPY)) + m_base_orientation ^= ORIENTATION_FLIP_Y; + + // set the orientation and layerconfig equal to the base + m_orientation = m_base_orientation; + m_layerconfig = m_base_layerconfig; + + // load the layout files + load_layout_files(layoutfile, flags & RENDER_CREATE_SINGLE_FILE); + + // set the current view to the first one + set_view(0); + + // make us the UI target if there is none + if (!hidden() && manager.m_ui_target == NULL) + manager.set_ui_target(*this); +} + + +//------------------------------------------------- +// ~render_target - destructor +//------------------------------------------------- + +render_target::~render_target() +{ + // free the layout files + while (m_filelist != NULL) + { + layout_file *temp = m_filelist; + m_filelist = temp->next; + layout_file_free(temp); + } +} + + +//------------------------------------------------- +// is_ui_target - return true if this is the +// UI target +//------------------------------------------------- + +bool render_target::is_ui_target() const +{ + return (this == &m_manager.ui_target()); +} + + +//------------------------------------------------- +// index - return the index of this target +//------------------------------------------------- + +int render_target::index() const +{ + return m_manager.m_targetlist.indexof(*this); +} + + +//------------------------------------------------- +// set_bounds - set the bounds and pixel aspect +// of a target +//------------------------------------------------- + +void render_target::set_bounds(INT32 width, INT32 height, float pixel_aspect) +{ + m_width = width; + m_height = height; + m_bounds.x0 = m_bounds.y0 = 0; + m_bounds.x1 = (float)width; + m_bounds.y1 = (float)height; + m_pixel_aspect = pixel_aspect; +} + + +//------------------------------------------------- +// set_layer_config - set the layer config of a +// target +//------------------------------------------------- + +void render_target::set_layer_config(int layerconfig) +{ + m_layerconfig = layerconfig; + layout_view_recompute(m_curview, layerconfig); +} + + +//------------------------------------------------- +// set_view - dynamically change the view for +// a target +//------------------------------------------------- + +void render_target::set_view(int viewindex) +{ + layout_view *view = view_by_index(viewindex); + if (view != NULL) + { + m_curview = view; + layout_view_recompute(view, m_layerconfig); + } +} + + +//------------------------------------------------- +// set_max_texture_size - set the upper bound on +// the texture size +//------------------------------------------------- + +void render_target::set_max_texture_size(int maxwidth, int maxheight) +{ + m_maxtexwidth = maxwidth; + m_maxtexheight = maxheight; +} + + +//------------------------------------------------- +// view_name - return the name of the given view +//------------------------------------------------- + +const char *render_target::view_name(int viewindex) +{ + layout_view *view = view_by_index(viewindex); + return (view != NULL) ? view->name : NULL; +} + + +//------------------------------------------------- +// render_target_get_view_screens - return a +// bitmask of which screens are visible on a +// given view +//------------------------------------------------- + +UINT32 render_target::view_screens(int viewindex) +{ + layout_view *view = view_by_index(viewindex); + return (view != NULL) ? view->screens : NULL; +} + + +//------------------------------------------------- +// compute_visible_area - compute the visible +// area for the given target with the current +// layout and proposed new parameters +//------------------------------------------------- + +void render_target::compute_visible_area(INT32 target_width, INT32 target_height, float target_pixel_aspect, int target_orientation, INT32 &visible_width, INT32 &visible_height) +{ + float width, height; + float scale; + + // constrained case + if (target_pixel_aspect != 0.0f) + { + // start with the aspect ratio of the square pixel layout + width = (zoom_to_screen() && m_curview->screens > 0) ? m_curview->scraspect : m_curview->aspect; + height = 1.0f; + + // first apply target orientation + if (target_orientation & ORIENTATION_SWAP_XY) + FSWAP(width, height); + + // apply the target pixel aspect ratio + height *= target_pixel_aspect; + + // based on the height/width ratio of the source and target, compute the scale factor + if (width / height > (float)target_width / (float)target_height) + scale = (float)target_width / width; + else + scale = (float)target_height / height; + } + + // stretch-to-fit case + else + { + width = (float)target_width; + height = (float)target_height; + scale = 1.0f; + } + + // set the final width/height + visible_width = render_round_nearest(width * scale); + visible_height = render_round_nearest(height * scale); +} + + +//------------------------------------------------- +// compute_minimum_size - compute the "minimum" +// size of a target, which is the smallest bounds +// that will ensure at least 1 target pixel per +// source pixel for all included screens +//------------------------------------------------- + +void render_target::compute_minimum_size(INT32 &minwidth, INT32 &minheight) +{ + float maxxscale = 1.0f, maxyscale = 1.0f; + int screens_considered = 0; + + // scan the current view for all screens + for (int layer = 0; layer < ITEM_LAYER_MAX; layer++) + + // iterate over items in the layer + for (view_item *item = m_curview->itemlist[layer]; item != NULL; item = item->next) + if (item->element == NULL) + { + const screen_device_config *scrconfig = downcast(m_manager.machine().config->m_devicelist.find(SCREEN, item->index)); + screen_device *screendev = m_manager.machine().device(scrconfig->tag()); + + // we may be called very early, before machine->visible_area is initialized; handle that case + const rectangle vectorvis = { 0, 639, 0, 479 }; + const rectangle *visarea = NULL; + if (scrconfig->screen_type() == SCREEN_TYPE_VECTOR) + visarea = &vectorvis; + else if (screendev != NULL && screendev->started()) + visarea = &screendev->visible_area(); + else + visarea = &scrconfig->visible_area(); + + // apply target orientation to the bounds + render_bounds bounds = item->bounds; + apply_orientation(bounds, m_orientation); + normalize_bounds(bounds); + + // based on the orientation of the screen container, check the bitmap + render_container *container = m_manager.m_screen_container_list.find(item->index); + float xscale, yscale; + if (!(orientation_add(m_orientation, container->orientation()) & ORIENTATION_SWAP_XY)) + { + xscale = (float)(visarea->max_x + 1 - visarea->min_x) / (bounds.x1 - bounds.x0); + yscale = (float)(visarea->max_y + 1 - visarea->min_y) / (bounds.y1 - bounds.y0); + } + else + { + xscale = (float)(visarea->max_y + 1 - visarea->min_y) / (bounds.x1 - bounds.x0); + yscale = (float)(visarea->max_x + 1 - visarea->min_x) / (bounds.y1 - bounds.y0); + } + + // pick the greater + maxxscale = MAX(xscale, maxxscale); + maxyscale = MAX(yscale, maxyscale); + screens_considered++; + } + + // if there were no screens considered, pick a nominal default + if (screens_considered == 0) + { + maxxscale = 640.0f; + maxyscale = 480.0f; + } + + // round up + minwidth = render_round_nearest(maxxscale); + minheight = render_round_nearest(maxyscale); +} + + +//------------------------------------------------- +// get_primitives - return a list of primitives +// for a given render target +//------------------------------------------------- + +render_primitive_list &render_target::get_primitives() +{ + // remember the base values if this is the first frame + if (m_base_view == NULL) + m_base_view = m_curview; + + // switch to the next primitive list + render_primitive_list &list = m_primlist[m_listindex]; + m_listindex = (m_listindex + 1) % ARRAY_LENGTH(m_primlist); + list.acquire_lock(); + + // free any previous primitives + list.release_all(); + + // compute the visible width/height + INT32 viswidth, visheight; + compute_visible_area(m_width, m_height, m_pixel_aspect, m_orientation, viswidth, visheight); + + // create a root transform for the target + object_transform root_xform; + root_xform.xoffs = (float)(m_width - viswidth) / 2; + root_xform.yoffs = (float)(m_height - visheight) / 2; + root_xform.xscale = (float)viswidth; + root_xform.yscale = (float)visheight; + root_xform.color.r = root_xform.color.g = root_xform.color.b = root_xform.color.a = 1.0f; + root_xform.orientation = m_orientation; + root_xform.no_center = false; + + // iterate over layers back-to-front, but only if we're running + if (m_manager.machine().phase() >= MACHINE_PHASE_RESET) + for (int layernum = 0; layernum < ITEM_LAYER_MAX; layernum++) + { + int blendmode; + int layer = get_layer_and_blendmode(*m_curview, layernum, blendmode); + if (m_curview->layenabled[layer]) + { + // iterate over items in the layer + for (view_item *item = m_curview->itemlist[layer]; item != NULL; item = item->next) + { + // first apply orientation to the bounds + render_bounds bounds = item->bounds; + apply_orientation(bounds, root_xform.orientation); + normalize_bounds(bounds); + + // apply the transform to the item + object_transform item_xform; + item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; + item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; + item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; + item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; + item_xform.color.r = item->color.r * root_xform.color.r; + item_xform.color.g = item->color.g * root_xform.color.g; + item_xform.color.b = item->color.b * root_xform.color.b; + item_xform.color.a = item->color.a * root_xform.color.a; + item_xform.orientation = orientation_add(item->orientation, root_xform.orientation); + item_xform.no_center = false; + + // if there is no associated element, it must be a screen element + if (item->element != NULL) + { + int state = 0; + if (item->output_name[0] != 0) + state = output_get_value(item->output_name); + else if (item->input_tag[0] != 0) + { + const input_field_config *field = input_field_by_tag_and_mask(m_manager.machine().m_portlist, item->input_tag, item->input_mask); + if (field != NULL) + state = ((input_port_read_safe(&m_manager.machine(), item->input_tag, 0) ^ field->defvalue) & item->input_mask) ? 1 : 0; + } + add_element_primitives(list, item_xform, *item->element, state, blendmode); + } + else + { + render_container *container = m_manager.m_screen_container_list.find(item->index); + add_container_primitives(list, item_xform, *container, blendmode); + } + } + } + } + + // if we are not in the running stage, draw an outer box + else + { + render_primitive *prim = list.alloc(render_primitive::QUAD); + set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); + set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f); + prim->texture.base = NULL; + prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + list.append(*prim); + + if (m_width > 1 && m_height > 1) + { + prim = list.alloc(render_primitive::QUAD); + set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1)); + set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); + prim->texture.base = NULL; + prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + list.append(*prim); + } + } + + // process the debug containers + for (render_container *debug = m_debug_containers.first(); debug != NULL; debug = debug->next()) + { + object_transform ui_xform; + ui_xform.xoffs = 0; + ui_xform.yoffs = 0; + ui_xform.xscale = (float)m_width; + ui_xform.yscale = (float)m_height; + ui_xform.color.r = ui_xform.color.g = ui_xform.color.b = ui_xform.color.a = 1.0f; + ui_xform.color.a = 0.9f; + ui_xform.orientation = m_orientation; + ui_xform.no_center = true; + + // add UI elements + add_container_primitives(list, ui_xform, *debug, BLENDMODE_ALPHA); + } + + // process the UI if we are the UI target + if (is_ui_target()) + { + // compute the transform for the UI + object_transform ui_xform; + ui_xform.xoffs = 0; + ui_xform.yoffs = 0; + ui_xform.xscale = (float) m_width; + ui_xform.yscale = (float) m_height; + ui_xform.color.r = ui_xform.color.g = ui_xform.color.b = ui_xform.color.a = 1.0f; + ui_xform.orientation = m_orientation; + ui_xform.no_center = false; + + // add UI elements + add_container_primitives(list, ui_xform, m_manager.ui_container(), BLENDMODE_ALPHA); + } + + // optimize the list before handing it off + add_clear_and_optimize_primitive_list(list); + list.release_lock(); + return list; +} + + +//------------------------------------------------- +// map_point_container - attempts to map a point +// on the specified render_target to the +// specified container, if possible +//------------------------------------------------- + +bool render_target::map_point_container(INT32 target_x, INT32 target_y, render_container &container, float &container_x, float &container_y) +{ + view_item *item; + return map_point_internal(target_x, target_y, &container, container_x, container_y, item); +} + + +//------------------------------------------------- +// map_point_input - attempts to map a point on +// the specified render_target to the specified +// container, if possible +//------------------------------------------------- + +bool render_target::map_point_input(INT32 target_x, INT32 target_y, const char *&input_tag, UINT32 &input_mask, float &input_x, float &input_y) +{ + view_item *item = NULL; + + bool result = map_point_internal(target_x, target_y, NULL, input_x, input_y, item); + if (result && item != NULL) + { + input_tag = item->input_tag; + input_mask = item->input_mask; + } + return result; +} + + +//------------------------------------------------- +// invalidate_all - if any of our primitive lists +// contain a reference to the given pointer, +// clear them +//------------------------------------------------- + +void render_target::invalidate_all(void *refptr) +{ + // iterate through all our primitive lists + for (int listnum = 0; listnum < ARRAY_LENGTH(m_primlist); listnum++) + { + render_primitive_list &list = m_primlist[listnum]; + + // if we have a reference to this object, release our list + list.acquire_lock(); + if (list.has_reference(refptr)) + list.release_all(); + list.release_lock(); + } +} + + +//------------------------------------------------- +// debug_alloc - allocate a container for a debug +// view +//------------------------------------------------- + +render_container *render_target::debug_alloc() +{ + return &m_debug_containers.append(*m_manager.container_alloc()); +} + + +//------------------------------------------------- +// debug_free - free a container for a debug view +//------------------------------------------------- + +void render_target::debug_free(render_container &container) +{ + m_debug_containers.remove(container); +} + + +//------------------------------------------------- +// debug_top - move a debug view container to +// the top of the list +//------------------------------------------------- + +void render_target::debug_top(render_container &container) +{ + m_debug_containers.prepend(m_debug_containers.detach(container)); +} + + +//------------------------------------------------- +// load_layout_files - load layout files for a +// given render target +//------------------------------------------------- + +void render_target::load_layout_files(const char *layoutfile, bool singlefile) +{ + layout_file **nextfile = &m_filelist; + + // if there's an explicit file, load that first + const char *basename = m_manager.machine().basename(); + if (layoutfile != NULL) + { + *nextfile = layout_file_load(m_manager.machine(), basename, layoutfile); + if (*nextfile != NULL) + nextfile = &(*nextfile)->next; + } + + // if we're only loading this file, we know our final result + if (singlefile) + return; + + // try to load a file based on the driver name + const game_driver *gamedrv = m_manager.machine().gamedrv; + *nextfile = layout_file_load(m_manager.machine(), basename, gamedrv->name); + if (*nextfile == NULL) + *nextfile = layout_file_load(m_manager.machine(), basename, "default"); + if (*nextfile != NULL) + nextfile = &(*nextfile)->next; + + // if a default view has been specified, use that as a fallback + if (gamedrv->default_layout != NULL) + { + *nextfile = layout_file_load(m_manager.machine(), NULL, gamedrv->default_layout); + if (*nextfile != NULL) + nextfile = &(*nextfile)->next; + } + if (m_manager.machine().m_config.m_default_layout != NULL) + { + *nextfile = layout_file_load(m_manager.machine(), NULL, m_manager.machine().m_config.m_default_layout); + if (*nextfile != NULL) + nextfile = &(*nextfile)->next; + } + + // try to load another file based on the parent driver name + const game_driver *cloneof = driver_get_clone(gamedrv); + if (cloneof != NULL) + { + *nextfile = layout_file_load(m_manager.machine(), cloneof->name, cloneof->name); + if (*nextfile == NULL) + *nextfile = layout_file_load(m_manager.machine(), cloneof->name, "default"); + if (*nextfile != NULL) + nextfile = &(*nextfile)->next; + } + + // now do the built-in layouts for single-screen games + if (screen_count(m_manager.machine().m_config) == 1) + { + if (gamedrv->flags & ORIENTATION_SWAP_XY) + *nextfile = layout_file_load(m_manager.machine(), NULL, layout_vertical); + else + *nextfile = layout_file_load(m_manager.machine(), NULL, layout_horizont); + assert_always(*nextfile != NULL, "Couldn't parse default layout??"); + nextfile = &(*nextfile)->next; + } +} + + +//------------------------------------------------- +// add_container_primitives - add primitives +// based on the container +//------------------------------------------------- + +void render_target::add_container_primitives(render_primitive_list &list, const object_transform &xform, render_container &container, int blendmode) +{ + // first update the palette for the container, if it is dirty + container.update_palette(); + + // compute the clip rect + render_bounds cliprect; + cliprect.x0 = xform.xoffs; + cliprect.y0 = xform.yoffs; + cliprect.x1 = xform.xoffs + xform.xscale; + cliprect.y1 = xform.yoffs + xform.yscale; + sect_render_bounds(&cliprect, &m_bounds); + + // compute the container transform + object_transform container_xform; + container_xform.orientation = orientation_add(container.orientation(), xform.orientation); + { + float xscale = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container.yscale() : container.xscale(); + float yscale = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container.xscale() : container.yscale(); + float xoffs = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container.yoffset() : container.xoffset(); + float yoffs = (container_xform.orientation & ORIENTATION_SWAP_XY) ? container.xoffset() : container.yoffset(); + if (container_xform.orientation & ORIENTATION_FLIP_X) xoffs = -xoffs; + if (container_xform.orientation & ORIENTATION_FLIP_Y) yoffs = -yoffs; + container_xform.xscale = xform.xscale * xscale; + container_xform.yscale = xform.yscale * yscale; + if (xform.no_center) + { + container_xform.xoffs = xform.xscale * (xoffs) + xform.xoffs; + container_xform.yoffs = xform.yscale * (yoffs) + xform.yoffs; + } + else + { + container_xform.xoffs = xform.xscale * (0.5f - 0.5f * xscale + xoffs) + xform.xoffs; + container_xform.yoffs = xform.yscale * (0.5f - 0.5f * yscale + yoffs) + xform.yoffs; + } + container_xform.color = xform.color; + } + + // iterate over elements + for (render_container::item *curitem = container.first_item(); curitem != NULL; curitem = curitem->next()) + { + // compute the oriented bounds + render_bounds bounds = curitem->bounds(); + apply_orientation(bounds, container_xform.orientation); + + // allocate the primitive and set the transformed bounds/color data + render_primitive *prim = list.alloc(render_primitive::INVALID); + prim->bounds.x0 = render_round_nearest(container_xform.xoffs + bounds.x0 * container_xform.xscale); + prim->bounds.y0 = render_round_nearest(container_xform.yoffs + bounds.y0 * container_xform.yscale); + if (curitem->internal() & INTERNAL_FLAG_CHAR) + { + prim->bounds.x1 = prim->bounds.x0 + render_round_nearest((bounds.x1 - bounds.x0) * container_xform.xscale); + prim->bounds.y1 = prim->bounds.y0 + render_round_nearest((bounds.y1 - bounds.y0) * container_xform.yscale); + } + else + { + prim->bounds.x1 = render_round_nearest(container_xform.xoffs + bounds.x1 * container_xform.xscale); + prim->bounds.y1 = render_round_nearest(container_xform.yoffs + bounds.y1 * container_xform.yscale); + } + + // compute the color of the primitive + prim->color.r = container_xform.color.r * curitem->color().r; + prim->color.g = container_xform.color.g * curitem->color().g; + prim->color.b = container_xform.color.b * curitem->color().b; + prim->color.a = container_xform.color.a * curitem->color().a; + + // now switch off the type + bool clipped = true; + switch (curitem->type()) + { + case CONTAINER_ITEM_LINE: + // adjust the color for brightness/contrast/gamma + prim->color.a = container.apply_brightness_contrast_gamma_fp(prim->color.a); + prim->color.r = container.apply_brightness_contrast_gamma_fp(prim->color.r); + prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g); + prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b); + + // set the line type + prim->type = render_primitive::LINE; + + // scale the width by the minimum of X/Y scale factors + prim->width = curitem->width() * MIN(container_xform.xscale, container_xform.yscale); + prim->flags = curitem->flags(); + + // clip the primitive + clipped = render_clip_line(&prim->bounds, &cliprect); + break; + + case CONTAINER_ITEM_QUAD: + // set the quad type + prim->type = render_primitive::QUAD; + + // normalize the bounds + normalize_bounds(prim->bounds); + + // get the scaled bitmap and set the resulting palette + if (curitem->texture() != NULL) + { + // determine the final orientation + int finalorient = orientation_add(PRIMFLAG_GET_TEXORIENT(curitem->flags()), container_xform.orientation); + + // based on the swap values, get the scaled final texture + int width = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.y1 - prim->bounds.y0) : (prim->bounds.x1 - prim->bounds.x0); + int height = (finalorient & ORIENTATION_SWAP_XY) ? (prim->bounds.x1 - prim->bounds.x0) : (prim->bounds.y1 - prim->bounds.y0); + width = MIN(width, m_maxtexwidth); + height = MIN(height, m_maxtexheight); + if (curitem->texture()->get_scaled(width, height, prim->texture, list)) + { + // set the palette + prim->texture.palette = curitem->texture()->get_adjusted_palette(container); + + // determine UV coordinates and apply clipping + prim->texcoords = oriented_texcoords[finalorient]; + clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); + + // apply the final orientation from the quad flags and then build up the final flags + prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | + PRIMFLAG_TEXORIENT(finalorient) | + PRIMFLAG_TEXFORMAT(curitem->texture()->format()); + if (blendmode != -1) + prim->flags |= PRIMFLAG_BLENDMODE(blendmode); + else + prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); + } + } + else + { + // adjust the color for brightness/contrast/gamma + prim->color.r = container.apply_brightness_contrast_gamma_fp(prim->color.r); + prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g); + prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b); + + // no texture -- set the basic flags + prim->texture.base = NULL; + prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + + // apply clipping + clipped = render_clip_quad(&prim->bounds, &cliprect, NULL); + } + break; + } + + // add to the list or free if we're clipped out + list.append_or_return(*prim, clipped); + } + + // add the overlay if it exists + if (container.overlay() != NULL && screen_overlay_enabled()) + { + INT32 width, height; + + // allocate a primitive + render_primitive *prim = list.alloc(render_primitive::QUAD); + set_render_bounds_wh(&prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale); + prim->color = container_xform.color; + width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0); + height = render_round_nearest(prim->bounds.y1) - render_round_nearest(prim->bounds.y0); + + bool got_scaled = container.overlay()->get_scaled( + (container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width, + (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list); + if (got_scaled) + { + // determine UV coordinates + prim->texcoords = oriented_texcoords[container_xform.orientation]; + + // set the flags and add it to the list + prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | + PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | + PRIMFLAG_TEXFORMAT(container.overlay()->format()); + } + list.append_or_return(*prim, !got_scaled); + } +} + + +//------------------------------------------------- +// add_element_primitives - add the primitive +// for an element in the current state +//------------------------------------------------- + +void render_target::add_element_primitives(render_primitive_list &list, const object_transform &xform, const layout_element &element, int state, int blendmode) +{ + // if we're out of range, bail + if (state > element.maxstate) + return; + if (state < 0) + state = 0; + + // get a pointer to the relevant texture + render_texture *texture = element.elemtex[state].texture; + if (texture != NULL) + { + render_primitive *prim = list.alloc(render_primitive::QUAD); + + // configure the basics + prim->color = xform.color; + prim->flags = PRIMFLAG_TEXORIENT(xform.orientation) | PRIMFLAG_BLENDMODE(blendmode) | PRIMFLAG_TEXFORMAT(texture->format()); + + // compute the bounds + INT32 width = render_round_nearest(xform.xscale); + INT32 height = render_round_nearest(xform.yscale); + set_render_bounds_wh(&prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height); + if (xform.orientation & ORIENTATION_SWAP_XY) + ISWAP(width, height); + width = MIN(width, m_maxtexwidth); + height = MIN(height, m_maxtexheight); + + // get the scaled texture and append it + bool clipped = true; + if (texture->get_scaled(width, height, prim->texture, list)) + { + // compute the clip rect + render_bounds cliprect; + cliprect.x0 = render_round_nearest(xform.xoffs); + cliprect.y0 = render_round_nearest(xform.yoffs); + cliprect.x1 = render_round_nearest(xform.xoffs + xform.xscale); + cliprect.y1 = render_round_nearest(xform.yoffs + xform.yscale); + sect_render_bounds(&cliprect, &m_bounds); + + // determine UV coordinates and apply clipping + prim->texcoords = oriented_texcoords[xform.orientation]; + clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); + } + + // add to the list or free if we're clipped out + list.append_or_return(*prim, clipped); + } +} + + +//------------------------------------------------- +// map_point_internal - internal logic for +// mapping points +//------------------------------------------------- + +bool render_target::map_point_internal(INT32 target_x, INT32 target_y, render_container *container, float &mapped_x, float &mapped_y, view_item *&mapped_item) +{ + // default to point not mapped + mapped_x = -1.0; + mapped_y = -1.0; + + // convert target coordinates to float + float target_fx = (float)target_x / m_width; + float target_fy = (float)target_y / m_height; + + // explicitly check for the UI container + if (container != NULL && container == &m_manager.ui_container()) + { + // this hit test went against the UI container + if (target_fx >= 0.0 && target_fx < 1.0 && target_fy >= 0.0 && target_fy < 1.0) + { + // this point was successfully mapped + mapped_x = target_fx; + mapped_y = target_fy; + mapped_item = NULL; + return true; + } + return false; + } + + // loop through each layer + for (int layernum = 0; layernum < ITEM_LAYER_MAX; layernum++) + { + int blendmode; + int layer = get_layer_and_blendmode(*m_curview, layernum, blendmode); + if (m_curview->layenabled[layer]) + { + // iterate over items in the layer + for (view_item *item = m_curview->itemlist[layer]; item != NULL; item = item->next) + { + bool checkit; + + // if we're looking for a particular container, verify that we have the right one + if (container != NULL) + checkit = (item->element == NULL && container == m_manager.m_screen_container_list.find(item->index)); + + // otherwise, assume we're looking for an input + else + checkit = (item->input_tag[0] != 0); + + // this target is worth looking at; now check the point + if (checkit && target_fx >= item->bounds.x0 && target_fx < item->bounds.x1 && target_fy >= item->bounds.y0 && target_fy < item->bounds.y1) + { + // point successfully mapped + mapped_x = (target_fx - item->bounds.x0) / (item->bounds.x1 - item->bounds.x0); + mapped_y = (target_fy - item->bounds.y0) / (item->bounds.y1 - item->bounds.y0); + mapped_item = item; + return true; + } + } + } + } + return false; +} + + +//------------------------------------------------- +// view_name - return the name of the indexed +// view, or NULL if it doesn't exist +//------------------------------------------------- + +layout_view *render_target::view_by_index(int index) const +{ + // scan the list of views within each layout, skipping those that don't apply + for (layout_file *file = m_filelist; file != NULL; file = file->next) + for (layout_view *view = file->viewlist; view != NULL; view = view->next) + if (!(m_flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) + if (index-- == 0) + return view; + return NULL; +} + + +//------------------------------------------------- +// view_index - return the index of the given +// view +//------------------------------------------------- + +int render_target::view_index(layout_view &targetview) const +{ + // find the first named match + int index = 0; + + // scan the list of views within each layout, skipping those that don't apply + for (layout_file *file = m_filelist; file != NULL; file = file->next) + for (layout_view *view = file->viewlist; view != NULL; view = view->next) + if (!(m_flags & RENDER_CREATE_NO_ART) || !layout_view_has_art(view)) + { + if (&targetview == view) + return index; + index++; + } + return 0; +} + + +//------------------------------------------------- +// config_load - process config information +//------------------------------------------------- + +void render_target::config_load(xml_data_node &targetnode) +{ + // find the view + const char *viewname = xml_get_attribute_string(&targetnode, "view", NULL); + if (viewname != NULL) + for (int viewnum = 0; viewnum < 1000; viewnum++) + { + const char *testname = view_name(viewnum); + if (testname == NULL) + break; + if (!strcmp(viewname, testname)) + { + set_view(viewnum); + break; + } + } + + // modify the artwork config + int tmpint = xml_get_attribute_int(&targetnode, "backdrops", -1); + if (tmpint == 0 || tmpint == 1) + set_backdrops_enabled(tmpint); + + tmpint = xml_get_attribute_int(&targetnode, "overlays", -1); + if (tmpint == 0 || tmpint == 1) + set_overlays_enabled(tmpint); + + tmpint = xml_get_attribute_int(&targetnode, "bezels", -1); + if (tmpint == 0 || tmpint == 1) + set_bezels_enabled(tmpint); + + tmpint = xml_get_attribute_int(&targetnode, "zoom", -1); + if (tmpint == 0 || tmpint == 1) + set_zoom_to_screen(tmpint); + + // apply orientation + tmpint = xml_get_attribute_int(&targetnode, "rotate", -1); + if (tmpint != -1) + { + if (tmpint == 90) + tmpint = ROT90; + else if (tmpint == 180) + tmpint = ROT180; + else if (tmpint == 270) + tmpint = ROT270; + else + tmpint = ROT0; + set_orientation(orientation_add(tmpint, orientation())); + + // apply the opposite orientation to the UI + if (is_ui_target()) + { + render_container::user_settings settings; + render_container &ui_container = m_manager.ui_container(); + + ui_container.get_user_settings(settings); + settings.m_orientation = orientation_add(orientation_reverse(tmpint), settings.m_orientation); + ui_container.set_user_settings(settings); + } + } +} + + +//------------------------------------------------- +// config_save - save our configuration, or +// return false if we are the same as the default +//------------------------------------------------- + +bool render_target::config_save(xml_data_node &targetnode) +{ + bool changed = false; + + // output the basics + xml_set_attribute_int(&targetnode, "index", index()); + + // output the view + if (m_curview != m_base_view) + { + xml_set_attribute(&targetnode, "view", m_curview->name); + changed = true; + } + + // output the layer config + if (m_layerconfig != m_base_layerconfig) + { + xml_set_attribute_int(&targetnode, "backdrops", backdrops_enabled()); + xml_set_attribute_int(&targetnode, "overlays", overlays_enabled()); + xml_set_attribute_int(&targetnode, "bezels", bezels_enabled()); + xml_set_attribute_int(&targetnode, "zoom", zoom_to_screen()); + changed = true; + } + + // output rotation + if (m_orientation != m_base_orientation) + { + int rotate = 0; + if (orientation_add(ROT90, m_base_orientation) == m_orientation) + rotate = 90; + else if (orientation_add(ROT180, m_base_orientation) == m_orientation) + rotate = 180; + else if (orientation_add(ROT270, m_base_orientation) == m_orientation) + rotate = 270; + assert(rotate != 0); + xml_set_attribute_int(&targetnode, "rotate", rotate); + changed = true; + } + + return changed; +} + + +//------------------------------------------------- +// init_clear_extents - reset the extents list +//------------------------------------------------- + +void render_target::init_clear_extents() +{ + m_clear_extents[0] = -m_height; + m_clear_extents[1] = 1; + m_clear_extents[2] = m_width; + m_clear_extent_count = 3; +} + + +//------------------------------------------------- +// remove_clear_extent - remove a quad from the +// list of stuff to clear, unless it overlaps +// a previous quad +//------------------------------------------------- + +bool render_target::remove_clear_extent(const render_bounds &bounds) +{ + INT32 *max = &m_clear_extents[MAX_CLEAR_EXTENTS]; + INT32 *last = &m_clear_extents[m_clear_extent_count]; + INT32 *ext = &m_clear_extents[0]; + INT32 boundsx0 = ceil(bounds.x0); + INT32 boundsx1 = floor(bounds.x1); + INT32 boundsy0 = ceil(bounds.y0); + INT32 boundsy1 = floor(bounds.y1); + INT32 y0, y1 = 0; + + // loop over Y extents + while (ext < last) + { + INT32 *linelast; + + // first entry of each line should always be negative + assert(ext[0] < 0.0f); + y0 = y1; + y1 = y0 - ext[0]; + + // do we intersect this extent? + if (boundsy0 < y1 && boundsy1 > y0) + { + INT32 *xext; + INT32 x0, x1 = 0; + + // split the top + if (y0 < boundsy0) + { + int diff = boundsy0 - y0; + + // make a copy of this extent + memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext)); + last += ext[1] + 2; + assert_always(last < max, "Ran out of clear extents!\n"); + + // split the extent between pieces + ext[ext[1] + 2] = -(-ext[0] - diff); + ext[0] = -diff; + + // advance to the new extent + y0 -= ext[0]; + ext += ext[1] + 2; + y1 = y0 - ext[0]; + } + + // split the bottom + if (y1 > boundsy1) + { + int diff = y1 - boundsy1; + + // make a copy of this extent + memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext)); + last += ext[1] + 2; + assert_always(last < max, "Ran out of clear extents!\n"); + + // split the extent between pieces + ext[ext[1] + 2] = -diff; + ext[0] = -(-ext[0] - diff); + + // recompute y1 + y1 = y0 - ext[0]; + } + + // now remove the X extent + linelast = &ext[ext[1] + 2]; + xext = &ext[2]; + while (xext < linelast) + { + x0 = x1; + x1 = x0 + xext[0]; + + // do we fully intersect this extent? + if (boundsx0 >= x0 && boundsx1 <= x1) + { + // yes; split it + memmove(&xext[2], &xext[0], (last - xext) * sizeof(*xext)); + last += 2; + linelast += 2; + assert_always(last < max, "Ran out of clear extents!\n"); + + // split this extent into three parts + xext[0] = boundsx0 - x0; + xext[1] = boundsx1 - boundsx0; + xext[2] = x1 - boundsx1; + + // recompute x1 + x1 = boundsx1; + xext += 2; + } + + // do we partially intersect this extent? + else if (boundsx0 < x1 && boundsx1 > x0) + goto abort; + + // advance + xext++; + + // do we partially intersect the next extent (which is a non-clear extent)? + if (xext < linelast) + { + x0 = x1; + x1 = x0 + xext[0]; + if (boundsx0 < x1 && boundsx1 > x0) + goto abort; + xext++; + } + } + + // update the count + ext[1] = linelast - &ext[2]; + } + + // advance to the next row + ext += 2 + ext[1]; + } + + // update the total count + m_clear_extent_count = last - &m_clear_extents[0]; + return true; + +abort: + // update the total count even on a failure as we may have split extents + m_clear_extent_count = last - &m_clear_extents[0]; + return false; +} + + +//------------------------------------------------- +// add_clear_extents - add the accumulated +// extents as a series of quads to clear +//------------------------------------------------- + +void render_target::add_clear_extents(render_primitive_list &list) +{ + simple_list clearlist; + INT32 *last = &m_clear_extents[m_clear_extent_count]; + INT32 *ext = &m_clear_extents[0]; + INT32 y0, y1 = 0; + + // loop over all extents + while (ext < last) + { + INT32 *linelast = &ext[ext[1] + 2]; + INT32 *xext = &ext[2]; + INT32 x0, x1 = 0; + + // first entry should always be negative + assert(ext[0] < 0); + y0 = y1; + y1 = y0 - ext[0]; + + // now remove the X extent + while (xext < linelast) + { + x0 = x1; + x1 = x0 + *xext++; + + // only add entries for non-zero widths + if (x1 - x0 > 0) + { + render_primitive *prim = list.alloc(render_primitive::QUAD); + set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); + set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); + prim->texture.base = NULL; + prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + clearlist.append(*prim); + } + + // skip the non-clearing extent + x0 = x1; + x1 = x0 + *xext++; + } + + // advance to the next part + ext += 2 + ext[1]; + } + + // we know that the first primitive in the list will be the global clip + // so we insert the clears immediately after + list.m_primlist.prepend_list(clearlist); +} + + +//------------------------------------------------- +// add_clear_and_optimize_primitive_list - +// optimize the primitive list +//------------------------------------------------- + +void render_target::add_clear_and_optimize_primitive_list(render_primitive_list &list) +{ + // start with the assumption that we need to clear the whole screen + init_clear_extents(); + + // scan the list until we hit an intersection quad or a line + for (render_primitive *prim = list.first(); prim != NULL; prim = prim->next()) + { + // switch off the type + switch (prim->type) + { + case render_primitive::LINE: + goto done; + + case render_primitive::QUAD: + { + // stop when we hit an alpha texture + if (PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_PALETTEA16) + goto done; + + // if this quad can't be cleanly removed from the extents list, we're done + if (!remove_clear_extent(prim->bounds)) + goto done; + + // change the blendmode on the first primitive to be NONE + if (PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_RGB_MULTIPLY) + { + // RGB multiply will multiply against 0, leaving nothing + set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); + prim->texture.base = NULL; + prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + } + else + { + // for alpha or add modes, we will blend against 0 or add to 0; treat it like none + prim->flags = (prim->flags & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE); + } + + // since alpha is disabled, premultiply the RGB values and reset the alpha to 1.0 + prim->color.r *= prim->color.a; + prim->color.g *= prim->color.a; + prim->color.b *= prim->color.a; + prim->color.a = 1.0f; + break; + } + + default: + throw emu_fatalerror("Unexpected primitive type"); + } + } + +done: + // now add the extents to the clear list + add_clear_extents(list); +} + + + +//************************************************************************** +// CORE IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// render_manager - constructor +//------------------------------------------------- + +render_manager::render_manager(running_machine &machine) + : m_machine(machine), + m_targetlist(machine.m_respool), + m_ui_target(NULL), + m_live_textures(0), + m_texture_allocator(machine.m_respool), + m_ui_container(auto_alloc(&machine, render_container(*this))), + m_screen_container_list(machine.m_respool) +{ + // register callbacks + config_register(&machine, "video", config_load_static, config_save_static); + + // create one container per screen + for (screen_device *screen = screen_first(machine); screen != NULL; screen = screen_next(screen)) + container_alloc(screen); +} + + +//------------------------------------------------- +// ~render_manager - destructor +//------------------------------------------------- + +render_manager::~render_manager() +{ + // better not be any outstanding textures when we die + assert(m_live_textures == 0); + + // free the UI container + container_free(m_ui_container); +} + + +//------------------------------------------------- +// is_live - return if the screen is 'live' +//------------------------------------------------- + +bool render_manager::is_live(screen_device &screen) const +{ + int screen_index = screen.machine->m_devicelist.index(SCREEN, screen.tag()); + assert(screen_index != -1); + + // iterate over all live targets and or together their screen masks + UINT32 bitmask = 0; + for (render_target *target = m_targetlist.first(); target != NULL; target = target->next()) + bitmask |= target->view_screens(target->view()); + + return (bitmask & (1 << screen_index)) ? true : false; +} + + +//------------------------------------------------- +// max_update_rate - return the smallest maximum +// update rate across all targets +//------------------------------------------------- + +float render_manager::max_update_rate() const +{ + // iterate over all live targets and or together their screen masks + float minimum = 0; + for (render_target *target = m_targetlist.first(); target != NULL; target = target->next()) + if (target->max_update_rate() != 0) + { + if (minimum == 0) + minimum = target->max_update_rate(); + else + minimum = MIN(target->max_update_rate(), minimum); + } + + return minimum; +} + + +//------------------------------------------------- +// target_alloc - allocate a new target +//------------------------------------------------- + +render_target *render_manager::target_alloc(const char *layoutfile, UINT32 flags) +{ + return &m_targetlist.append(*auto_alloc(&m_machine, render_target(*this, layoutfile, flags))); +} + + +//------------------------------------------------- +// target_free - free a target +//------------------------------------------------- + +void render_manager::target_free(render_target *target) +{ + if (target != NULL) + m_targetlist.remove(*target); +} + + +//------------------------------------------------- +// target_by_index - get a render_target by index +//------------------------------------------------- + +render_target *render_manager::target_by_index(int index) const +{ + // count up the targets until we hit the requested index + for (render_target *target = m_targetlist.first(); target != NULL; target = target->next()) + if (!target->hidden()) + if (index-- == 0) + return target; + return NULL; +} + + +//------------------------------------------------- +// ui_aspect - return the aspect ratio for UI +// fonts +//------------------------------------------------- + +float render_manager::ui_aspect() +{ + int orient = orientation_add(m_ui_target->orientation(), m_ui_container->orientation()); + + // based on the orientation of the target, compute height/width or width/height + float aspect; + if (!(orient & ORIENTATION_SWAP_XY)) + aspect = (float)m_ui_target->height() / (float)m_ui_target->width(); + else + aspect = (float)m_ui_target->width() / (float)m_ui_target->height(); + + // if we have a valid pixel aspect, apply that and return + if (m_ui_target->pixel_aspect() != 0.0f) + return aspect / m_ui_target->pixel_aspect(); + + // if not, clamp for extreme proportions + if (aspect < 0.66f) + aspect = 0.66f; + if (aspect > 1.5f) + aspect = 1.5f; + return aspect; +} + + +//------------------------------------------------- +// container_for_screen - return the container +// allocated for the given screen device +//------------------------------------------------- + +render_container *render_manager::container_for_screen(screen_device *screen) +{ + // scan the list of screen containers for a match + for (render_container *container = m_screen_container_list.first(); container != NULL; container = container->next()) + if (container->screen() == screen) + return container; + return NULL; +} + + +//------------------------------------------------- +// texture_alloc - allocate a new texture +//------------------------------------------------- + +render_texture *render_manager::texture_alloc(texture_scaler_func scaler, void *param) +{ + // allocate a new texture and reset it + render_texture *tex = m_texture_allocator.alloc(); + tex->reset(*this, scaler, param); + m_live_textures++; + return tex; +} + + +//------------------------------------------------- +// texture_free - release a texture +//------------------------------------------------- + +void render_manager::texture_free(render_texture *texture) +{ + if (texture != NULL) + m_live_textures--; + m_texture_allocator.reclaim(texture); +} + + +//------------------------------------------------- +// invalidate_all - remove all refs to a +// particular reference pointer +//------------------------------------------------- + +void render_manager::invalidate_all(void *refptr) +{ + // permit NULL + if (refptr == NULL) + return; + + // loop over targets + for (render_target *target = m_targetlist.first(); target != NULL; target = target->next()) + target->invalidate_all(refptr); +} + + +//------------------------------------------------- +// container_alloc - allocate a new container +//------------------------------------------------- + +render_container *render_manager::container_alloc(screen_device *screen) +{ + render_container *container = auto_alloc(&m_machine, render_container(*this, screen)); + if (screen != NULL) + m_screen_container_list.append(*container); return container; } -void render_debug_free(render_target *target, render_container *container) -{ - if (container == target->debug_containers) - { - target->debug_containers = container->next; - } - else - { - render_container *c; +//------------------------------------------------- +// container_free - release a container +//------------------------------------------------- - for (c = target->debug_containers; c != NULL; c = c->next) - if (c->next == container) - break; - c->next = container->next; - } - render_container_free(container); +void render_manager::container_free(render_container *container) +{ + m_screen_container_list.detach(*container); + auto_free(&m_machine, container); } -void render_debug_top(render_target *target, render_container *container) +//------------------------------------------------- +// config_load - read and apply data from the +// configuration file +//------------------------------------------------- + +void render_manager::config_load_static(running_machine *machine, int config_type, xml_data_node *parentnode) { - /* remove */ - if (container == target->debug_containers) - { - target->debug_containers = container->next; - } - else - { - render_container *c; + machine->render().config_load(config_type, parentnode); +} - for (c = target->debug_containers; c != NULL; c = c->next) - if (c->next == container) - break; - c->next = container->next; - } - /* add to end */ - if (target->debug_containers == NULL) - target->debug_containers = container; - else - { - render_container *c; +void render_manager::config_load(int config_type, xml_data_node *parentnode) +{ + // we only care about game files + if (config_type != CONFIG_TYPE_GAME) + return; - for (c = target->debug_containers; c != NULL; c = c->next) - if (c->next == NULL) - break; - c->next = container; + // might not have any data + if (parentnode == NULL) + return; + + // check the UI target + xml_data_node *uinode = xml_get_sibling(parentnode->child, "interface"); + if (uinode != NULL) + { + render_target *target = target_by_index(xml_get_attribute_int(uinode, "target", 0)); + if (target != NULL) + set_ui_target(*target); + } + + // iterate over target nodes + for (xml_data_node *targetnode = xml_get_sibling(parentnode->child, "target"); targetnode; targetnode = xml_get_sibling(targetnode->next, "target")) + { + render_target *target = target_by_index(xml_get_attribute_int(targetnode, "index", -1)); + if (target != NULL) + target->config_load(*targetnode); + } + + // iterate over screen nodes + for (xml_data_node *screennode = xml_get_sibling(parentnode->child, "screen"); screennode; screennode = xml_get_sibling(screennode->next, "screen")) + { + int index = xml_get_attribute_int(screennode, "index", -1); + render_container *container = m_screen_container_list.find(index); + render_container::user_settings settings; + + // fetch current settings + container->get_user_settings(settings); + + // fetch color controls + settings.m_brightness = xml_get_attribute_float(screennode, "brightness", settings.m_brightness); + settings.m_contrast = xml_get_attribute_float(screennode, "contrast", settings.m_contrast); + settings.m_gamma = xml_get_attribute_float(screennode, "gamma", settings.m_gamma); + + // fetch positioning controls + settings.m_xoffset = xml_get_attribute_float(screennode, "hoffset", settings.m_xoffset); + settings.m_xscale = xml_get_attribute_float(screennode, "hstretch", settings.m_xscale); + settings.m_yoffset = xml_get_attribute_float(screennode, "voffset", settings.m_yoffset); + settings.m_yscale = xml_get_attribute_float(screennode, "vstretch", settings.m_yscale); + + // set the new values + container->set_user_settings(settings); } - container->next = NULL; } +//------------------------------------------------- +// config_save - save data to the configuration +// file +//------------------------------------------------- + +void render_manager::config_save_static(running_machine *machine, int config_type, xml_data_node *parentnode) +{ + machine->render().config_save(config_type, parentnode); +} + +void render_manager::config_save(int config_type, xml_data_node *parentnode) +{ + // we only care about game files + if (config_type != CONFIG_TYPE_GAME) + return; + + // write out the interface target + if (m_ui_target->index() != 0) + { + // create a node for it + xml_data_node *uinode = xml_add_child(parentnode, "interface", NULL); + if (uinode != NULL) + xml_set_attribute_int(uinode, "target", m_ui_target->index()); + } + + // iterate over targets + for (int targetnum = 0; targetnum < 1000; targetnum++) + { + // get this target and break when we fail + render_target *target = target_by_index(targetnum); + if (target == NULL) + break; + + // create a node + xml_data_node *targetnode = xml_add_child(parentnode, "target", NULL); + if (targetnode != NULL && !target->config_save(*targetnode)) + xml_delete_node(targetnode); + } + + // iterate over screen containers + int scrnum = 0; + for (render_container *container = m_screen_container_list.first(); container != NULL; container = container->next(), scrnum++) + { + // create a node + xml_data_node *screennode = xml_add_child(parentnode, "screen", NULL); + if (screennode != NULL) + { + bool changed = false; + + // output the basics + xml_set_attribute_int(screennode, "index", scrnum); + + render_container::user_settings settings; + container->get_user_settings(settings); + + // output the color controls + if (settings.m_brightness != options_get_float(m_machine.options(), OPTION_BRIGHTNESS)) + { + xml_set_attribute_float(screennode, "brightness", settings.m_brightness); + changed = true; + } + + if (settings.m_contrast != options_get_float(m_machine.options(), OPTION_CONTRAST)) + { + xml_set_attribute_float(screennode, "contrast", settings.m_contrast); + changed = true; + } + + if (settings.m_gamma != options_get_float(m_machine.options(), OPTION_GAMMA)) + { + xml_set_attribute_float(screennode, "gamma", settings.m_gamma); + changed = true; + } + + // output the positioning controls + if (settings.m_xoffset != 0.0f) + { + xml_set_attribute_float(screennode, "hoffset", settings.m_xoffset); + changed = true; + } + + if (settings.m_xscale != 1.0f) + { + xml_set_attribute_float(screennode, "hstretch", settings.m_xscale); + changed = true; + } + + if (settings.m_yoffset != 0.0f) + { + xml_set_attribute_float(screennode, "voffset", settings.m_yoffset); + changed = true; + } + + if (settings.m_yscale != 1.0f) + { + xml_set_attribute_float(screennode, "vstretch", settings.m_yscale); + changed = true; + } + + // if nothing changed, kill the node + if (!changed) + xml_delete_node(screennode); + } + } +} diff --git a/src/emu/render.h b/src/emu/render.h index 72cd7d467b1..7f15e8fffb0 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -4,9 +4,72 @@ Core rendering routines for MAME. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**************************************************************************** + + Theory of operation + ------------------- + + A render "target" is described by 5 parameters: + + - width = width, in pixels + - height = height, in pixels + - bpp = depth, in bits per pixel + - orientation = orientation of the target + - pixel_aspect = aspect ratio of the pixels + + Width, height, and bpp are self-explanatory. The remaining parameters + need some additional explanation. + + Regarding orientation, there are three orientations that need to be + dealt with: target orientation, UI orientation, and game orientation. + In the current model, the UI orientation tracks the target orientation + so that the UI is (in theory) facing the correct direction. The game + orientation is specified by the game driver and indicates how the + game and artwork are rotated. + + Regarding pixel_aspect, this is the aspect ratio of the individual + pixels, not the aspect ratio of the screen. You can determine this by + dividing the aspect ratio of the screen by the aspect ratio of the + resolution. For example, a 4:3 screen displaying 640x480 gives a + pixel aspect ratio of (4/3)/(640/480) = 1.0, meaning the pixels are + square. That same screen displaying 1280x1024 would have a pixel + aspect ratio of (4/3)/(1280/1024) = 1.06666, meaning the pixels are + slightly wider than they are tall. + + Artwork is always assumed to be a 1.0 pixel aspect ratio. The game + screens themselves can be variable aspect ratios. + ***************************************************************************/ #ifndef __RENDER_H__ @@ -18,451 +81,622 @@ -/*************************************************************************** +//************************************************************************** +// CONSTANTS +//************************************************************************** - Theory of operation - ------------------- - - A render "target" is described by 5 parameters: - - - width = width, in pixels - - height = height, in pixels - - bpp = depth, in bits per pixel - - orientation = orientation of the target - - pixel_aspect = aspect ratio of the pixels - - Width, height, and bpp are self-explanatory. The remaining parameters - need some additional explanation. - - Regarding orientation, there are three orientations that need to be - dealt with: target orientation, UI orientation, and game orientation. - In the current model, the UI orientation tracks the target orientation - so that the UI is (in theory) facing the correct direction. The game - orientation is specified by the game driver and indicates how the - game and artwork are rotated. - - Regarding pixel_aspect, this is the aspect ratio of the individual - pixels, not the aspect ratio of the screen. You can determine this by - dividing the aspect ratio of the screen by the aspect ratio of the - resolution. For example, a 4:3 screen displaying 640x480 gives a - pixel aspect ratio of (4/3)/(640/480) = 1.0, meaning the pixels are - square. That same screen displaying 1280x1024 would have a pixel - aspect ratio of (4/3)/(1280/1024) = 1.06666, meaning the pixels are - slightly wider than they are tall. - - Artwork is always assumed to be a 1.0 pixel aspect ratio. The game - screens themselves can be variable aspect ratios. - -***************************************************************************/ - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* render primitive types */ +// texture formats enum { - RENDER_PRIMITIVE_LINE, /* a single line */ - RENDER_PRIMITIVE_QUAD /* a rectilinear quad */ + TEXFORMAT_UNDEFINED = 0, // require a format to be specified + TEXFORMAT_PALETTE16, // 16bpp palettized, alpha ignored + TEXFORMAT_PALETTEA16, // 16bpp palettized, alpha respected + TEXFORMAT_RGB15, // 16bpp 5-5-5 RGB + TEXFORMAT_RGB32, // 32bpp 8-8-8 RGB + TEXFORMAT_ARGB32, // 32bpp 8-8-8-8 ARGB + TEXFORMAT_YUY16 // 16bpp 8-8 Y/Cb, Y/Cr in sequence +}; + +// blending modes +enum +{ + BLENDMODE_NONE = 0, // no blending + BLENDMODE_ALPHA, // standard alpha blend + BLENDMODE_RGB_MULTIPLY, // apply source alpha to source pix, then multiply RGB values + BLENDMODE_ADD // apply source alpha to source pix, then add to destination }; -/* render creation flags */ -#define RENDER_CREATE_NO_ART 0x01 /* ignore any views that have art in them */ -#define RENDER_CREATE_SINGLE_FILE 0x02 /* only load views from the file specified */ -#define RENDER_CREATE_HIDDEN 0x04 /* don't make this target visible */ - -/* layer config masks */ -#define LAYER_CONFIG_ENABLE_BACKDROP 0x01 /* enable backdrop layers */ -#define LAYER_CONFIG_ENABLE_OVERLAY 0x02 /* enable overlay layers */ -#define LAYER_CONFIG_ENABLE_BEZEL 0x04 /* enable bezel layers */ -#define LAYER_CONFIG_ZOOM_TO_SCREEN 0x08 /* zoom to screen area by default */ -#define LAYER_CONFIG_ENABLE_SCREEN_OVERLAY 0x10 /* enable screen overlays */ - -#define LAYER_CONFIG_DEFAULT (LAYER_CONFIG_ENABLE_BACKDROP | \ - LAYER_CONFIG_ENABLE_OVERLAY | \ - LAYER_CONFIG_ENABLE_BEZEL | \ - LAYER_CONFIG_ENABLE_SCREEN_OVERLAY) - -/* texture formats */ -enum -{ - TEXFORMAT_UNDEFINED = 0, /* require a format to be specified */ - TEXFORMAT_PALETTE16, /* 16bpp palettized, alpha ignored */ - TEXFORMAT_PALETTEA16, /* 16bpp palettized, alpha respected */ - TEXFORMAT_RGB15, /* 16bpp 5-5-5 RGB */ - TEXFORMAT_RGB32, /* 32bpp 8-8-8 RGB */ - TEXFORMAT_ARGB32, /* 32bpp 8-8-8-8 ARGB */ - TEXFORMAT_YUY16 /* 16bpp 8-8 Y/Cb, Y/Cr in sequence */ -}; - -/* blending modes */ -enum -{ - BLENDMODE_NONE = 0, /* no blending */ - BLENDMODE_ALPHA, /* standard alpha blend */ - BLENDMODE_RGB_MULTIPLY, /* apply source alpha to source pix, then multiply RGB values */ - BLENDMODE_ADD /* apply source alpha to source pix, then add to destination */ -}; +// render creation flags +const UINT8 RENDER_CREATE_NO_ART = 0x01; // ignore any views that have art in them +const UINT8 RENDER_CREATE_SINGLE_FILE = 0x02; // only load views from the file specified +const UINT8 RENDER_CREATE_HIDDEN = 0x04; // don't make this target visible -/* flags for primitives */ -#define PRIMFLAG_TEXORIENT_SHIFT 0 -#define PRIMFLAG_TEXORIENT_MASK (15 << PRIMFLAG_TEXORIENT_SHIFT) +// layer config masks +const UINT8 LAYER_CONFIG_ENABLE_BACKDROP = 0x01; // enable backdrop layers +const UINT8 LAYER_CONFIG_ENABLE_OVERLAY = 0x02; // enable overlay layers +const UINT8 LAYER_CONFIG_ENABLE_BEZEL = 0x04; // enable bezel layers +const UINT8 LAYER_CONFIG_ZOOM_TO_SCREEN = 0x08; // zoom to screen area by default +const UINT8 LAYER_CONFIG_ENABLE_SCREEN_OVERLAY = 0x10; // enable screen overlays + +const UINT8 LAYER_CONFIG_DEFAULT = (LAYER_CONFIG_ENABLE_BACKDROP | + LAYER_CONFIG_ENABLE_OVERLAY | + LAYER_CONFIG_ENABLE_BEZEL | + LAYER_CONFIG_ENABLE_SCREEN_OVERLAY); + + +// flags for primitives +const int PRIMFLAG_TEXORIENT_SHIFT = 0; +const UINT32 PRIMFLAG_TEXORIENT_MASK = 15 << PRIMFLAG_TEXORIENT_SHIFT; + +const int PRIMFLAG_TEXFORMAT_SHIFT = 4; +const UINT32 PRIMFLAG_TEXFORMAT_MASK = 15 << PRIMFLAG_TEXFORMAT_SHIFT; + +const int PRIMFLAG_BLENDMODE_SHIFT = 8; +const UINT32 PRIMFLAG_BLENDMODE_MASK = 15 << PRIMFLAG_BLENDMODE_SHIFT; + +const int PRIMFLAG_ANTIALIAS_SHIFT = 12; +const UINT32 PRIMFLAG_ANTIALIAS_MASK = 1 << PRIMFLAG_ANTIALIAS_SHIFT; + +const int PRIMFLAG_SCREENTEX_SHIFT = 13; +const UINT32 PRIMFLAG_SCREENTEX_MASK = 1 << PRIMFLAG_SCREENTEX_SHIFT; + +const int PRIMFLAG_TEXWRAP_SHIFT = 14; +const UINT32 PRIMFLAG_TEXWRAP_MASK = 1 << PRIMFLAG_TEXWRAP_SHIFT; + + + +//************************************************************************** +// MACROS +//************************************************************************** + #define PRIMFLAG_TEXORIENT(x) ((x) << PRIMFLAG_TEXORIENT_SHIFT) #define PRIMFLAG_GET_TEXORIENT(x) (((x) & PRIMFLAG_TEXORIENT_MASK) >> PRIMFLAG_TEXORIENT_SHIFT) -#define PRIMFLAG_TEXFORMAT_SHIFT 4 -#define PRIMFLAG_TEXFORMAT_MASK (15 << PRIMFLAG_TEXFORMAT_SHIFT) #define PRIMFLAG_TEXFORMAT(x) ((x) << PRIMFLAG_TEXFORMAT_SHIFT) #define PRIMFLAG_GET_TEXFORMAT(x) (((x) & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT) -#define PRIMFLAG_BLENDMODE_SHIFT 8 -#define PRIMFLAG_BLENDMODE_MASK (15 << PRIMFLAG_BLENDMODE_SHIFT) #define PRIMFLAG_BLENDMODE(x) ((x) << PRIMFLAG_BLENDMODE_SHIFT) #define PRIMFLAG_GET_BLENDMODE(x) (((x) & PRIMFLAG_BLENDMODE_MASK) >> PRIMFLAG_BLENDMODE_SHIFT) -#define PRIMFLAG_ANTIALIAS_SHIFT 12 -#define PRIMFLAG_ANTIALIAS_MASK (1 << PRIMFLAG_ANTIALIAS_SHIFT) #define PRIMFLAG_ANTIALIAS(x) ((x) << PRIMFLAG_ANTIALIAS_SHIFT) #define PRIMFLAG_GET_ANTIALIAS(x) (((x) & PRIMFLAG_ANTIALIAS_MASK) >> PRIMFLAG_ANTIALIAS_SHIFT) -#define PRIMFLAG_SCREENTEX_SHIFT 13 -#define PRIMFLAG_SCREENTEX_MASK (1 << PRIMFLAG_SCREENTEX_SHIFT) #define PRIMFLAG_SCREENTEX(x) ((x) << PRIMFLAG_SCREENTEX_SHIFT) #define PRIMFLAG_GET_SCREENTEX(x) (((x) & PRIMFLAG_SCREENTEX_MASK) >> PRIMFLAG_SCREENTEX_SHIFT) -#define PRIMFLAG_TEXWRAP_SHIFT 14 -#define PRIMFLAG_TEXWRAP_MASK (1 << PRIMFLAG_TEXWRAP_SHIFT) #define PRIMFLAG_TEXWRAP(x) ((x) << PRIMFLAG_TEXWRAP_SHIFT) #define PRIMFLAG_GET_TEXWRAP(x) (((x) & PRIMFLAG_TEXWRAP_MASK) >> PRIMFLAG_TEXWRAP_SHIFT) -/*************************************************************************** - MACROS -***************************************************************************/ - -/* convenience macros for adding items to the UI container */ -#define render_container_add_point(c, x0,y0,diam,argb,flags) render_container_add_line(c, x0, y0, x0, y0, diam, argb, flags) -#define render_container_add_rect(c, x0,y0,x1,y1,argb,flags) render_container_add_quad(c, x0, y0, x1, y1, argb, NULL, flags) - -/* convenience macros for adding items to a screen container */ -#define render_screen_add_point(scr,x0,y0,diam,argb,flags) render_container_add_line(render_container_get_screen(scr), x0, y0, x0, y0, diam, argb, flags) -#define render_screen_add_line(scr,x0,y0,x1,y1,diam,argb,flags) render_container_add_line(render_container_get_screen(scr), x0, y0, x1, y1, diam, argb, flags) -#define render_screen_add_rect(scr,x0,y0,x1,y1,argb,flags) render_container_add_quad(render_container_get_screen(scr), x0, y0, x1, y1, argb, NULL, flags) -#define render_screen_add_quad(scr,x0,y0,x1,y1,argb,tex,flags) render_container_add_quad(render_container_get_screen(scr), x0, y0, x1, y1, argb, tex, flags) -#define render_screen_add_char(scr,x0,y0,ht,asp,argb,font,ch) render_container_add_char(render_container_get_screen(scr), x0, y0, ht, asp, argb, font, ch) - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** // forward definitions class device_t; -class device_config; class screen_device; - - -/*------------------------------------------------- - callbacks --------------------------------------------------*/ - -/* texture scaling callback */ -typedef void (*texture_scaler_func)(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); - - - -/*------------------------------------------------- - opaque types --------------------------------------------------*/ - -typedef struct _render_container render_container; -class render_target; -struct render_texture; +class render_container; +class render_manager; +typedef struct _xml_data_node xml_data_node; typedef struct _render_font render_font; -typedef struct _render_ref render_ref; +struct object_transform; +typedef struct _layout_element layout_element; +typedef struct _layout_view layout_view; +typedef struct _view_item view_item; +typedef struct _layout_file layout_file; +// texture scaling callback +typedef void (*texture_scaler_func)(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param); -/*------------------------------------------------- - render_bounds - floating point bounding - rectangle --------------------------------------------------*/ -typedef struct _render_bounds render_bounds; -struct _render_bounds +// render_bounds - floating point bounding rectangle +struct render_bounds { - float x0; /* leftmost X coordinate */ - float y0; /* topmost Y coordinate */ - float x1; /* rightmost X coordinate */ - float y1; /* bottommost Y coordinate */ + float x0; // leftmost X coordinate + float y0; // topmost Y coordinate + float x1; // rightmost X coordinate + float y1; // bottommost Y coordinate }; -/*------------------------------------------------- - render_color - floating point set of ARGB - values --------------------------------------------------*/ - -typedef struct _render_color render_color; -struct _render_color +// render_color - floating point set of ARGB values +struct render_color { - float a; /* alpha component (0.0 = transparent, 1.0 = opaque) */ - float r; /* red component (0.0 = none, 1.0 = max) */ - float g; /* green component (0.0 = none, 1.0 = max) */ - float b; /* blue component (0.0 = none, 1.0 = max) */ + float a; // alpha component (0.0 = transparent, 1.0 = opaque) + float r; // red component (0.0 = none, 1.0 = max) + float g; // green component (0.0 = none, 1.0 = max) + float b; // blue component (0.0 = none, 1.0 = max) }; -/*------------------------------------------------- - render_texuv - floating point set of UV - texture coordinates --------------------------------------------------*/ - -typedef struct _render_texuv render_texuv; -struct _render_texuv +// render_texuv - floating point set of UV texture coordinates +struct render_texuv { - float u; /* U coodinate (0.0-1.0) */ - float v; /* V coordinate (0.0-1.0) */ + float u; // U coodinate (0.0-1.0) + float v; // V coordinate (0.0-1.0) }; -/*------------------------------------------------- - render_quad_texuv - floating point set of UV - texture coordinates --------------------------------------------------*/ - -typedef struct _render_quad_texuv render_quad_texuv; -struct _render_quad_texuv +// render_quad_texuv - floating point set of UV texture coordinates +struct render_quad_texuv { - render_texuv tl; /* top-left UV coordinate */ - render_texuv tr; /* top-right UV coordinate */ - render_texuv bl; /* bottom-left UV coordinate */ - render_texuv br; /* bottom-right UV coordinate */ + render_texuv tl; // top-left UV coordinate + render_texuv tr; // top-right UV coordinate + render_texuv bl; // bottom-left UV coordinate + render_texuv br; // bottom-right UV coordinate }; -/*------------------------------------------------- - render_texinfo - texture information --------------------------------------------------*/ - -typedef struct _render_texinfo render_texinfo; -struct _render_texinfo +// render_texinfo - texture information +struct render_texinfo { - void * base; /* base of the data */ - UINT32 rowpixels; /* pixels per row */ - UINT32 width; /* width of the image */ - UINT32 height; /* height of the image */ - const rgb_t * palette; /* palette for PALETTE16 textures, LUTs for RGB15/RGB32 */ - UINT32 seqid; /* sequence ID */ + void * base; // base of the data + UINT32 rowpixels; // pixels per row + UINT32 width; // width of the image + UINT32 height; // height of the image + const rgb_t * palette; // palette for PALETTE16 textures, LUTs for RGB15/RGB32 + UINT32 seqid; // sequence ID }; -/*------------------------------------------------- - render_primitive - a single low-level - primitive for the rendering engine --------------------------------------------------*/ +// ======================> render_primitive -typedef struct _render_primitive render_primitive; -struct _render_primitive +// render_primitive - a single low-level primitive for the rendering engine +class render_primitive { - render_primitive * next; /* pointer to next element */ - int type; /* type of primitive */ - render_bounds bounds; /* bounds or positions */ - render_color color; /* RGBA values */ - UINT32 flags; /* flags */ - float width; /* width (for line primitives) */ - render_texinfo texture; /* texture info (for quad primitives) */ - render_quad_texuv texcoords; /* texture coordinates (for quad primitives) */ + friend class simple_list; + +public: + // render primitive types + enum primitive_type + { + INVALID = 0, // invalid type + LINE, // a single line + QUAD // a rectilinear quad + }; + + // getters + render_primitive *next() const { return m_next; } + + // reset to prepare for re-use + void reset(); + + // public state + primitive_type type; // type of primitive + render_bounds bounds; // bounds or positions + render_color color; // RGBA values + UINT32 flags; // flags + float width; // width (for line primitives) + render_texinfo texture; // texture info (for quad primitives) + render_quad_texuv texcoords; // texture coordinates (for quad primitives) + +private: + // internal state + render_primitive * m_next; // pointer to next element }; -/*------------------------------------------------- - render_primitive_list - an object containing - a list head plus a lock --------------------------------------------------*/ +// ======================> render_primitive_list -typedef struct _render_primitive_list render_primitive_list; -struct _render_primitive_list +// render_primitive_list - an object containing a list head plus a lock +class render_primitive_list { - render_primitive * head; /* head of the list */ - render_primitive ** nextptr; /* pointer to the next tail pointer */ - osd_lock * lock; /* should only should be accessed under this lock */ - render_ref * reflist; /* list of references */ + friend class render_target; + + // construction/destruction + render_primitive_list(); + ~render_primitive_list(); + +public: + // getters + render_primitive *first() const { return m_primlist.first(); } + + // lock management + void acquire_lock() { osd_lock_acquire(m_lock); } + void release_lock() { osd_lock_release(m_lock); } + + // reference management + void add_reference(void *refptr); + bool has_reference(void *refptr) const; + +private: + // helpers for our friends to manipulate the list + render_primitive *alloc(render_primitive::primitive_type type); + void release_all(); + void append(render_primitive &prim) { append_or_return(prim, false); } + void append_or_return(render_primitive &prim, bool clipped); + + // a reference is an abstract reference to an internal object of some sort + class reference + { + public: + reference *next() const { return m_next; } + reference * m_next; // link to the next reference + void * m_refptr; // reference pointer + }; + + // internal state + simple_list m_primlist; // list of primitives + simple_list m_reflist; // list of references + + fixed_allocator m_primitive_allocator;// allocator for primitives + fixed_allocator m_reference_allocator; // allocator for references + + osd_lock * m_lock; // lock to protect list accesses }; -/*------------------------------------------------- - render_container_user_settings - an object - containing user-controllable settings for - a container --------------------------------------------------*/ +// ======================> render_texture -typedef struct _render_container_user_settings render_container_user_settings; -struct _render_container_user_settings +// a render_texture is used to track transformations when building an object list +class render_texture { - int orientation; /* orientation */ - float brightness; /* brightness */ - float contrast; /* contrast */ - float gamma; /* gamma */ - float xscale; /* horizontal scale factor */ - float yscale; /* vertical scale factor */ - float xoffset; /* horizontal offset */ - float yoffset; /* vertical offset */ + friend resource_pool_object::~resource_pool_object(); + friend class simple_list; + friend class fixed_allocator; + friend class render_manager; + friend class render_target; + + // construction/destruction + render_texture(); + ~render_texture(); + + // reset before re-use + void reset(render_manager &manager, texture_scaler_func scaler = NULL, void *param = NULL); + +public: + // getters + int format() const { return m_format; } + + // configure the texture bitmap + void set_bitmap(bitmap_t *bitmap, const rectangle *sbounds, int format, palette_t *palette = NULL); + + // generic high-quality bitmap scaler + static void hq_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param); + +private: + // internal helpers + bool get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &texinfo, render_primitive_list &primlist); + const rgb_t *get_adjusted_palette(render_container &container); + + static const int MAX_TEXTURE_SCALES = 8; + + // a scaled_texture contains a single scaled entry for a texture + struct scaled_texture + { + bitmap_t * bitmap; // final bitmap + UINT32 seqid; // sequence number + }; + + // internal state + render_manager * m_manager; // reference to our manager + render_texture * m_next; // next texture (for free list) + bitmap_t * m_bitmap; // pointer to the original bitmap + rectangle m_sbounds; // source bounds within the bitmap + palette_t * m_palette; // palette associated with the texture + int m_format; // format of the texture data + texture_scaler_func m_scaler; // scaling callback + void * m_param; // scaling callback parameter + UINT32 m_curseq; // current sequence number + scaled_texture m_scaled[MAX_TEXTURE_SCALES];// array of scaled variants of this texture + rgb_t * m_bcglookup; // dynamically allocated B/C/G lookup table + UINT32 m_bcglookup_entries; // number of B/C/G lookup entries allocated }; +// ======================> render_container -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ +// a render_container holds a list of items and an orientation for the entire collection +class render_container +{ + friend resource_pool_object::~resource_pool_object(); + friend class simple_list; + friend class render_manager; + friend class render_target; + + // construction/destruction + render_container(render_manager &manager, screen_device *screen = NULL); + ~render_container(); + +public: + // user settings describes the collected user-controllable settings + struct user_settings + { + // construction/destruction + user_settings(); + + // public state + int m_orientation; // orientation + float m_brightness; // brightness + float m_contrast; // contrast + float m_gamma; // gamma + float m_xscale; // horizontal scale factor + float m_yscale; // vertical scale factor + float m_xoffset; // horizontal offset + float m_yoffset; // vertical offset + }; + + // getters + render_container *next() const { return m_next; } + screen_device *screen() const { return m_screen; } + render_manager &manager() const { return m_manager; } + render_texture *overlay() const { return m_overlaytexture; } + int orientation() const { return m_user.m_orientation; } + float xscale() const { return m_user.m_xscale; } + float yscale() const { return m_user.m_yscale; } + float xoffset() const { return m_user.m_xoffset; } + float yoffset() const { return m_user.m_yoffset; } + bool is_empty() const { return (m_itemlist.count() == 0); } + void get_user_settings(user_settings &settings) const { settings = m_user; } + + // setters + void set_overlay(bitmap_t *bitmap); + void set_user_settings(const user_settings &settings); + + // empty the item list + void empty() { m_item_allocator.reclaim_all(m_itemlist); } + + // add items to the list + void add_line(float x0, float y0, float x1, float y1, float width, rgb_t argb, UINT32 flags); + void add_quad(float x0, float y0, float x1, float y1, rgb_t argb, render_texture *texture, UINT32 flags); + void add_char(float x0, float y0, float height, float aspect, rgb_t argb, render_font &font, UINT16 ch); + void add_point(float x0, float y0, float diameter, rgb_t argb, UINT32 flags) { add_line(x0, y0, x0, y0, diameter, argb, flags); } + void add_rect(float x0, float y0, float x1, float y1, rgb_t argb, UINT32 flags) { add_quad(x0, y0, x1, y1, argb, NULL, flags); } + + // brightness/contrast/gamma helpers + bool has_brightness_contrast_gamma_changes() const { return (m_user.m_brightness != 1.0f || m_user.m_contrast != 1.0f || m_user.m_gamma != 1.0f); } + UINT8 apply_brightness_contrast_gamma(UINT8 value); + float apply_brightness_contrast_gamma_fp(float value); + const rgb_t *bcg_lookup_table(int texformat, palette_t *palette = NULL); + +private: + // an item describes a high level primitive that is added to a container + class item + { + friend class render_container; + friend class simple_list; + + public: + // getters + item *next() const { return m_next; } + UINT8 type() const { return m_type; } + const render_bounds &bounds() const { return m_bounds; } + const render_color &color() const { return m_color; } + UINT32 flags() const { return m_flags; } + UINT32 internal() const { return m_internal; } + float width() const { return m_width; } + render_texture *texture() const { return m_texture; } + + private: + // internal state + item * m_next; // pointer to the next element in the list + UINT8 m_type; // type of element + render_bounds m_bounds; // bounds of the element + render_color m_color; // RGBA factors + UINT32 m_flags; // option flags + UINT32 m_internal; // internal flags + float m_width; // width of the line (lines only) + render_texture * m_texture; // pointer to the source texture (quads only) + }; + + // generic screen overlay scaler + static void overlay_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param); + + // internal helpers + item *first_item() const { return m_itemlist.first(); } + item &add_generic(UINT8 type, float x0, float y0, float x1, float y1, rgb_t argb); + void recompute_lookups(); + void update_palette(); + + // internal state + render_container * m_next; // the next container in the list + render_manager & m_manager; // reference back to the owning manager + simple_list m_itemlist; // head of the item list + fixed_allocator m_item_allocator; // free container items + screen_device * m_screen; // the screen device + user_settings m_user; // user settings + bitmap_t * m_overlaybitmap; // overlay bitmap + render_texture * m_overlaytexture; // overlay texture + palette_client * m_palclient; // client to the system palette + rgb_t m_bcglookup256[0x400]; // lookup table for brightness/contrast/gamma + rgb_t m_bcglookup32[0x80]; // lookup table for brightness/contrast/gamma + rgb_t m_bcglookup[0x10000]; // full palette lookup with bcg adjustements +}; -/* ----- core implementation ----- */ +// ======================> render_target -/* allocate base structures for the rendering system */ -void render_init(running_machine *machine); +// a render_target describes a surface that is being rendered to +class render_target +{ + friend resource_pool_object::~resource_pool_object(); + friend class simple_list; + friend class render_manager; -/* return a boolean indicating if the screen is live */ -int render_is_live_screen(device_t *screen); + // construction/destruction + render_target(render_manager &manager, const char *layoutfile = NULL, UINT32 flags = 0); + ~render_target(); -/* return the smallest maximum update rate across all targets */ -float render_get_max_update_rate(void); +public: + // getters + render_target *next() const { return m_next; } + render_manager &manager() const { return m_manager; } + UINT32 width() const { return m_width; } + UINT32 height() const { return m_height; } + float pixel_aspect() const { return m_pixel_aspect; } + float max_update_rate() const { return m_max_refresh; } + int orientation() const { return m_orientation; } + int layer_config() const { return m_layerconfig; } + int view() const { return view_index(*m_curview); } + bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); } + bool backdrops_enabled() const { return (m_layerconfig & LAYER_CONFIG_ENABLE_BACKDROP) != 0; } + bool overlays_enabled() const { return (m_layerconfig & LAYER_CONFIG_ENABLE_OVERLAY) != 0; } + bool bezels_enabled() const { return (m_layerconfig & LAYER_CONFIG_ENABLE_BEZEL) != 0; } + bool screen_overlay_enabled() const { return (m_layerconfig & LAYER_CONFIG_ENABLE_SCREEN_OVERLAY) != 0; } + bool zoom_to_screen() const { return (m_layerconfig & LAYER_CONFIG_ZOOM_TO_SCREEN) != 0; } + bool is_ui_target() const; + int index() const; + + // setters + void set_bounds(INT32 width, INT32 height, float pixel_aspect = 0); + void set_max_update_rate(float updates_per_second) { m_max_refresh = updates_per_second; } + void set_orientation(int orientation) { m_orientation = orientation; } + void set_layer_config(int layerconfig); + void set_view(int viewindex); + void set_max_texture_size(int maxwidth, int maxheight); + void set_backdrops_enabled(bool enable) { if (enable) m_layerconfig |= LAYER_CONFIG_ENABLE_BACKDROP; else m_layerconfig &= ~LAYER_CONFIG_ENABLE_BACKDROP; } + void set_overlays_enabled(bool enable) { if (enable) m_layerconfig |= LAYER_CONFIG_ENABLE_OVERLAY; else m_layerconfig &= ~LAYER_CONFIG_ENABLE_OVERLAY; } + void set_bezels_enabled(bool enable) { if (enable) m_layerconfig |= LAYER_CONFIG_ENABLE_BEZEL; else m_layerconfig &= ~LAYER_CONFIG_ENABLE_BEZEL; } + void set_screen_overlay_enabled(bool enable) { if (enable) m_layerconfig |= LAYER_CONFIG_ENABLE_SCREEN_OVERLAY; else m_layerconfig &= ~LAYER_CONFIG_ENABLE_SCREEN_OVERLAY; } + void set_zoom_to_screen(bool zoom) { if (zoom) m_layerconfig |= LAYER_CONFIG_ZOOM_TO_SCREEN; else m_layerconfig &= ~LAYER_CONFIG_ZOOM_TO_SCREEN; } -/* select the UI target */ -void render_set_ui_target(render_target *target); + // view information + const char *view_name(int viewindex); + UINT32 view_screens(int viewindex); -/* return the UI target */ -render_target *render_get_ui_target(void); + // bounds computations + void compute_visible_area(INT32 target_width, INT32 target_height, float target_pixel_aspect, int target_orientation, INT32 &visible_width, INT32 &visible_height); + void compute_minimum_size(INT32 &minwidth, INT32 &minheight); -/* return the aspect ratio for UI fonts */ -float render_get_ui_aspect(void); + // get a primitive list + render_primitive_list &get_primitives(); + + // hit testing + bool map_point_container(INT32 target_x, INT32 target_y, render_container &container, float &container_x, float &container_y); + bool map_point_input(INT32 target_x, INT32 target_y, const char *&input_tag, UINT32 &input_mask, float &input_x, float &input_y); + + // reference tracking + void invalidate_all(void *refptr); + + // debug containers + render_container *debug_alloc(); + void debug_free(render_container &container); + void debug_top(render_container &container); + +private: + // internal helpers + void load_layout_files(const char *layoutfile, bool singlefile); + void add_container_primitives(render_primitive_list &list, const object_transform &xform, render_container &container, int blendmode); + void add_element_primitives(render_primitive_list &list, const object_transform &xform, const layout_element &element, int state, int blendmode); + bool map_point_internal(INT32 target_x, INT32 target_y, render_container *container, float &mapped_x, float &mapped_y, view_item *&mapped_item); + + // config callbacks + void config_load(xml_data_node &targetnode); + bool config_save(xml_data_node &targetnode); + + // view lookups + layout_view *view_by_index(int index) const; + int view_index(layout_view &view) const; + + // optimized clearing + void init_clear_extents(); + bool remove_clear_extent(const render_bounds &bounds); + void add_clear_extents(render_primitive_list &list); + void add_clear_and_optimize_primitive_list(render_primitive_list &list); + + // constants + static const int NUM_PRIMLISTS = 3; + static const int MAX_CLEAR_EXTENTS = 1000; + + // internal state + render_target * m_next; // link to next target + render_manager & m_manager; // reference to our owning manager + layout_view * m_curview; // current view + layout_file * m_filelist; // list of layout files + UINT32 m_flags; // creation flags + render_primitive_list m_primlist[NUM_PRIMLISTS]; // list of primitives + int m_listindex; // index of next primlist to use + INT32 m_width; // width in pixels + INT32 m_height; // height in pixels + render_bounds m_bounds; // bounds of the target + float m_pixel_aspect; // aspect ratio of individual pixels + float m_max_refresh; // maximum refresh rate, 0 or if none + int m_orientation; // orientation + int m_layerconfig; // layer configuration + layout_view * m_base_view; // the view at the time of first frame + int m_base_orientation; // the orientation at the time of first frame + int m_base_layerconfig; // the layer configuration at the time of first frame + int m_maxtexwidth; // maximum width of a texture + int m_maxtexheight; // maximum height of a texture + simple_list m_debug_containers; // list of debug containers + INT32 m_clear_extent_count; // number of clear extents + INT32 m_clear_extents[MAX_CLEAR_EXTENTS]; // array of clear extents +}; +// ======================> render_manager -/* ----- render target management ----- */ +// contains machine-global information and operations +class render_manager +{ + friend class render_target; + +public: + // construction/destruction + render_manager(running_machine &machine); + ~render_manager(); + + // getters + running_machine &machine() const { return m_machine; } + + // global queries + bool is_live(screen_device &screen) const; + float max_update_rate() const; + + // targets + render_target *target_alloc(const char *layoutfile = NULL, UINT32 flags = 0); + void target_free(render_target *target); + render_target *first_target() const { return m_targetlist.first(); } + render_target *target_by_index(int index) const; + + // UI targets + render_target &ui_target() const { assert(m_ui_target != NULL); return *m_ui_target; } + void set_ui_target(render_target &target) { m_ui_target = ⌖ } + float ui_aspect(); + + // screen containers + render_container *container_for_screen(screen_device *screen); + + // UI containers + render_container &ui_container() const { assert(m_ui_container != NULL); return *m_ui_container; } + + // textures + render_texture *texture_alloc(texture_scaler_func scaler = NULL, void *param = NULL); + void texture_free(render_texture *texture); -/* allocate a new render target */ -render_target *render_target_alloc(running_machine *machine, const char *layout, UINT32 flags); + // reference tracking + void invalidate_all(void *refptr); -/* free memory for a render target */ -void render_target_free(render_target *target); +private: + // containers + render_container *container_alloc(screen_device *screen = NULL); + void container_free(render_container *container); -/* get a render_target by index */ -render_target *render_target_get_indexed(int index); + // config callbacks + static void config_load_static(running_machine *machine, int config_type, xml_data_node *parentnode); + static void config_save_static(running_machine *machine, int config_type, xml_data_node *parentnode); + void config_load(int config_type, xml_data_node *parentnode); + void config_save(int config_type, xml_data_node *parentnode); -/* return the name of the indexed view, or NULL if it doesn't exist */ -const char *render_target_get_view_name(render_target *target, int viewindex); + // internal state + running_machine & m_machine; // reference back to the machine -/* return a bitmask of which screens are visible on a given view */ -UINT32 render_target_get_view_screens(render_target *target, int viewindex); + // array of live targets + simple_list m_targetlist; // list of targets + render_target * m_ui_target; // current UI target + + // texture lists + UINT32 m_live_textures; // number of live textures + fixed_allocator m_texture_allocator;// texture allocator -/* get the bounds and pixel aspect of a target */ -void render_target_get_bounds(render_target *target, INT32 *width, INT32 *height, float *pixel_aspect); - -/* set the bounds and pixel aspect of a target */ -void render_target_set_bounds(render_target *target, INT32 width, INT32 height, float pixel_aspect); - -/* get the maximum update rate (refresh rate) of a target, or 0 if no maximum */ -float render_target_get_max_update_rate(render_target *target); - -/* set the maximum update rate (refresh rate) of a target, or 0 if no maximum */ -void render_target_set_max_update_rate(render_target *target, float updates_per_second); - -/* get the orientation of a target */ -int render_target_get_orientation(render_target *target); - -/* set the orientation of a target */ -void render_target_set_orientation(render_target *target, int orientation); - -/* get the layer config of a target */ -int render_target_get_layer_config(render_target *target); - -/* set the layer config of a target */ -void render_target_set_layer_config(render_target *target, int layerconfig); - -/* return the currently selected view index */ -int render_target_get_view(render_target *target); - -/* dynamically change the view for a target */ -void render_target_set_view(render_target *target, int viewindex); - -/* set the upper bound on the texture size */ -void render_target_set_max_texture_size(render_target *target, int maxwidth, int maxheight); - -/* compute the visible area for the given target with the current layout and proposed new parameters */ -void render_target_compute_visible_area(render_target *target, INT32 target_width, INT32 target_height, float target_pixel_aspect, int target_orientation, INT32 *visible_width, INT32 *visible_height); - -/* get the "minimum" size of a target, which is the smallest bounds that will ensure at least - 1 target pixel per source pixel for all included screens */ -void render_target_get_minimum_size(render_target *target, INT32 *minwidth, INT32 *minheight); - -/* return a list of primitives for a given render target */ -const render_primitive_list *render_target_get_primitives(render_target *target); - -/* attempts to map a point on the specified render_target to the specified container, if possible */ -int render_target_map_point_container(render_target *target, INT32 target_x, INT32 target_y, render_container *container, float *container_x, float *container_y); - -/* attempts to map a point on the specified render_target to the specified container, if possible */ -int render_target_map_point_input(render_target *target, INT32 target_x, INT32 target_y, const char **input_tag, UINT32 *input_mask, float *input_x, float *input_y); + // containers for the UI and for screens + render_container * m_ui_container; // UI container + simple_list m_screen_container_list; // list of containers for the screen +}; - -/* ----- render texture management ----- */ - -/* allocate a new texture */ -render_texture *render_texture_alloc(texture_scaler_func scaler, void *param); - -/* free an allocated texture */ -void render_texture_free(render_texture *texture); - -/* set a new source bitmap */ -void render_texture_set_bitmap(render_texture *texture, bitmap_t *bitmap, const rectangle *sbounds, int format, palette_t *palette); - -/* generic high quality resampling scaler */ -void render_texture_hq_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); - - - -/* ----- render containers ----- */ - -/* empty a container in preparation for new stuff */ -void render_container_empty(render_container *container); - -/* return true if a container has nothing in it */ -int render_container_is_empty(render_container *container); - -/* get the current user settings for a container */ -void render_container_get_user_settings(render_container *container, render_container_user_settings *settings); - -/* set the current user settings for a container */ -void render_container_set_user_settings(render_container *container, const render_container_user_settings *settings); - -/* set the overlay bitmap for the container */ -void render_container_set_overlay(render_container *container, bitmap_t *bitmap); - -/* return a pointer to the UI container */ -render_container *render_container_get_ui(void); - -/* return a pointer to the container for the given screen */ -render_container *render_container_get_screen(screen_device *screen); - -/* add a line item to the specified container */ -void render_container_add_line(render_container *container, float x0, float y0, float x1, float y1, float width, rgb_t argb, UINT32 flags); - -/* add a quad item to the specified container */ -void render_container_add_quad(render_container *container, float x0, float y0, float x1, float y1, rgb_t argb, render_texture *texture, UINT32 flags); - -/* add a char item to the specified container */ -void render_container_add_char(render_container *container, float x0, float y0, float height, float aspect, rgb_t argb, render_font *font, UINT16 ch); - -/* "drawable" handling for internal debugger */ -render_container *render_debug_alloc(render_target *target); -void render_debug_free(render_target *target, render_container *container); -void render_debug_top(render_target *target, render_container *container); - -#endif /* __RENDER_H__ */ +#endif // __RENDER_H__ diff --git a/src/emu/rendersw.c b/src/emu/rendersw.c index 670b68db9cd..459f878c669 100644 --- a/src/emu/rendersw.c +++ b/src/emu/rendersw.c @@ -2333,24 +2333,27 @@ static void FUNC_PREFIX(setup_and_draw_textured_quad)(const render_primitive *pr using a software rasterizer -------------------------------------------------*/ -static void FUNC_PREFIX(draw_primitives)(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch) +static void FUNC_PREFIX(draw_primitives)(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch) { const render_primitive *prim; /* loop over the list and render each element */ - for (prim = primlist; prim != NULL; prim = prim->next) + for (prim = primlist.first(); prim != NULL; prim = prim->next()) switch (prim->type) { - case RENDER_PRIMITIVE_LINE: + case render_primitive::LINE: FUNC_PREFIX(draw_line)(prim, dstdata, width, height, pitch); break; - case RENDER_PRIMITIVE_QUAD: + case render_primitive::QUAD: if (!prim->texture.base) FUNC_PREFIX(draw_rect)(prim, dstdata, width, height, pitch); else FUNC_PREFIX(setup_and_draw_textured_quad)(prim, dstdata, width, height, pitch); break; + + default: + throw emu_fatalerror("Unexpected render_primitive type"); } } diff --git a/src/emu/rendfont.c b/src/emu/rendfont.c index 933946769ec..2fa5ba6f4ba 100644 --- a/src/emu/rendfont.c +++ b/src/emu/rendfont.c @@ -52,6 +52,7 @@ struct _render_font_char /*typedef struct _render_font render_font; -- defined in rendfont.h */ struct _render_font { + running_machine * machine; int format; /* format of font data */ int height; /* height of the font, from ascent to descent */ int yoffs; /* y offset from baseline to descent */ @@ -136,7 +137,7 @@ INLINE render_font_char *get_char(render_font *font, unicode_char chnum) and load the BDF file -------------------------------------------------*/ -render_font *render_font_alloc(const char *filename) +render_font *render_font_alloc(running_machine &machine, const char *filename) { file_error filerr; mame_file *ramfile; @@ -144,6 +145,7 @@ render_font *render_font_alloc(const char *filename) /* allocate and clear memory */ font = global_alloc_clear(render_font); + font->machine = &machine; /* attempt to load the cached version of the font first */ if (filename != NULL && render_font_load_cached_bdf(font, filename) == 0) @@ -152,6 +154,7 @@ render_font *render_font_alloc(const char *filename) /* if we failed, clean up and realloc */ render_font_free(font); font = global_alloc_clear(render_font); + font->machine = &machine; /* load the raw data instead */ filerr = mame_fopen_ram(font_uismall, sizeof(font_uismall), OPEN_FLAG_READ, &ramfile); @@ -183,8 +186,7 @@ void render_font_free(render_font *font) for (charnum = 0; charnum < 256; charnum++) { render_font_char *ch = &font->chars[tablenum][charnum]; - if (ch->texture != NULL) - render_texture_free(ch->texture); + font->machine->render().texture_free(ch->texture); global_free(ch->bitmap); } @@ -274,8 +276,8 @@ static void render_font_char_expand(render_font *font, render_font_char *ch) } /* wrap a texture around the bitmap */ - ch->texture = render_texture_alloc(render_texture_hq_scale, NULL); - render_texture_set_bitmap(ch->texture, ch->bitmap, NULL, TEXFORMAT_ARGB32, NULL); + ch->texture = font->machine->render().texture_alloc(render_texture::hq_scale); + ch->texture->set_bitmap(ch->bitmap, NULL, TEXFORMAT_ARGB32); } @@ -343,7 +345,11 @@ void render_font_get_scaled_bitmap_and_bounds(render_font *font, bitmap_t *dest, origheight = dest->height; dest->width = bounds->max_x - bounds->min_x; dest->height = bounds->max_y - bounds->min_y; - render_texture_hq_scale(dest, ch->bitmap, NULL, NULL); + rectangle clip; + clip.min_x = clip.min_y = 0; + clip.max_x = ch->bitmap->width - 1; + clip.max_y = ch->bitmap->height - 1; + render_texture::hq_scale(*dest, *ch->bitmap, clip, NULL); dest->width = origwidth; dest->height = origheight; } @@ -812,8 +818,7 @@ static int render_font_save_cached(render_font *font, const char *filename, UINT goto error; /* free the bitmap and texture */ - if (ch->texture != NULL) - render_texture_free(ch->texture); + font->machine->render().texture_free(ch->texture); ch->texture = NULL; global_free(ch->bitmap); ch->bitmap = NULL; diff --git a/src/emu/rendfont.h b/src/emu/rendfont.h index 36445c248b8..d8656b1ac0e 100644 --- a/src/emu/rendfont.h +++ b/src/emu/rendfont.h @@ -20,7 +20,7 @@ FUNCTION PROTOTYPES ***************************************************************************/ -render_font *render_font_alloc(const char *filename); +render_font *render_font_alloc(running_machine &machine, const char *filename); void render_font_free(render_font *font); INT32 render_font_get_pixel_height(render_font *font); render_texture *render_font_get_char_texture_and_bounds(render_font *font, float height, float aspect, unicode_char ch, render_bounds *bounds); diff --git a/src/emu/rendlay.c b/src/emu/rendlay.c index b997522d278..023e144732c 100644 --- a/src/emu/rendlay.c +++ b/src/emu/rendlay.c @@ -149,26 +149,26 @@ struct _element_component ***************************************************************************/ /* layout elements */ -static void layout_element_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); -static void layout_element_draw_rect(bitmap_t *dest, const rectangle *bounds, const render_color *color); -static void layout_element_draw_disk(bitmap_t *dest, const rectangle *bounds, const render_color *color); -static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, const render_color *color, const char *string); -static void layout_element_draw_led7seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); -static void layout_element_draw_led14seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); -static void layout_element_draw_led16seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); -static void layout_element_draw_led14segsc(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); -static void layout_element_draw_led16segsc(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); -static void layout_element_draw_dotmatrix(bitmap_t *dest, const rectangle *bounds, const render_color *color, int state); +static void layout_element_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param); +static void layout_element_draw_rect(bitmap_t &dest, const rectangle &bounds, const render_color &color); +static void layout_element_draw_disk(bitmap_t &dest, const rectangle &bounds, const render_color &color); +static void layout_element_draw_text(running_machine &machine, bitmap_t &dest, const rectangle &bounds, const render_color &color, const char *string); +static void layout_element_draw_led7seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); +static void layout_element_draw_led14seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); +static void layout_element_draw_led16seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); +static void layout_element_draw_led14segsc(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); +static void layout_element_draw_led16segsc(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); +static void layout_element_draw_dotmatrix(bitmap_t &dest, const rectangle &bounds, const render_color &color, int state); /* layout file parsing */ -static layout_element *load_layout_element(const machine_config *config, xml_data_node *elemnode, const char *dirname); -static element_component *load_element_component(const machine_config *config, xml_data_node *compnode, const char *dirname); -static layout_view *load_layout_view(const machine_config *config, xml_data_node *viewnode, layout_element *elemlist); -static view_item *load_view_item(const machine_config *config, xml_data_node *itemnode, layout_element *elemlist); +static layout_element *load_layout_element(running_machine &machine, xml_data_node *elemnode, const char *dirname); +static element_component *load_element_component(running_machine &machine, xml_data_node *compnode, const char *dirname); +static layout_view *load_layout_view(running_machine &machine, xml_data_node *viewnode, layout_element *elemlist); +static view_item *load_view_item(running_machine &machine, xml_data_node *itemnode, layout_element *elemlist); static bitmap_t *load_component_bitmap(const char *dirname, const char *file, const char *alphafile, int *hasalpha); -static int load_bounds(const machine_config *config, xml_data_node *boundsnode, render_bounds *bounds); -static int load_color(const machine_config *config, xml_data_node *colornode, render_color *color); -static int load_orientation(const machine_config *config, xml_data_node *orientnode, int *orientation); +static int load_bounds(running_machine &machine, xml_data_node *boundsnode, render_bounds *bounds); +static int load_color(running_machine &machine, xml_data_node *colornode, render_color *color); +static int load_orientation(running_machine &machine, xml_data_node *orientnode, int *orientation); static void layout_view_free(layout_view *view); static void layout_element_free(layout_element *element); @@ -351,7 +351,7 @@ void layout_view_recompute(layout_view *view, int layerconfig) appropriate resolution -------------------------------------------------*/ -static void layout_element_scale(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param) +static void layout_element_scale(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param) { element_texture *elemtex = (element_texture *)param; element_component *component; @@ -363,10 +363,10 @@ static void layout_element_scale(bitmap_t *dest, const bitmap_t *source, const r rectangle bounds; /* get the local scaled bounds */ - bounds.min_x = render_round_nearest(component->bounds.x0 * dest->width); - bounds.min_y = render_round_nearest(component->bounds.y0 * dest->height); - bounds.max_x = render_round_nearest(component->bounds.x1 * dest->width); - bounds.max_y = render_round_nearest(component->bounds.y1 * dest->height); + bounds.min_x = render_round_nearest(component->bounds.x0 * dest.width); + bounds.min_y = render_round_nearest(component->bounds.y0 * dest.height); + bounds.max_x = render_round_nearest(component->bounds.x1 * dest.width); + bounds.max_y = render_round_nearest(component->bounds.y1 * dest.height); /* based on the component type, add to the texture */ switch (component->type) @@ -375,47 +375,47 @@ static void layout_element_scale(bitmap_t *dest, const bitmap_t *source, const r if (component->bitmap == NULL) component->bitmap = load_component_bitmap(component->dirname, component->imagefile, component->alphafile, &component->hasalpha); render_resample_argb_bitmap_hq( - BITMAP_ADDR32(dest, bounds.min_y, bounds.min_x), - dest->rowpixels, + BITMAP_ADDR32(&dest, bounds.min_y, bounds.min_x), + dest.rowpixels, bounds.max_x - bounds.min_x, bounds.max_y - bounds.min_y, component->bitmap, NULL, &component->color); break; case COMPONENT_TYPE_RECT: - layout_element_draw_rect(dest, &bounds, &component->color); + layout_element_draw_rect(dest, bounds, component->color); break; case COMPONENT_TYPE_DISK: - layout_element_draw_disk(dest, &bounds, &component->color); + layout_element_draw_disk(dest, bounds, component->color); break; case COMPONENT_TYPE_TEXT: - layout_element_draw_text(dest, &bounds, &component->color, component->string); + layout_element_draw_text(*elemtex->element->machine, dest, bounds, component->color, component->string); break; case COMPONENT_TYPE_LED7SEG: - layout_element_draw_led7seg(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_led7seg(dest, bounds, component->color, elemtex->state); break; case COMPONENT_TYPE_LED14SEG: - layout_element_draw_led14seg(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_led14seg(dest, bounds, component->color, elemtex->state); break; case COMPONENT_TYPE_LED16SEG: - layout_element_draw_led16seg(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_led16seg(dest, bounds, component->color, elemtex->state); break; case COMPONENT_TYPE_LED14SEGSC: - layout_element_draw_led14segsc(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_led14segsc(dest, bounds, component->color, elemtex->state); break; case COMPONENT_TYPE_LED16SEGSC: - layout_element_draw_led16segsc(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_led16segsc(dest, bounds, component->color, elemtex->state); break; case COMPONENT_TYPE_DOTMATRIX: - layout_element_draw_dotmatrix(dest, &bounds, &component->color, elemtex->state); + layout_element_draw_dotmatrix(dest, bounds, component->color, elemtex->state); break; } } @@ -427,20 +427,20 @@ static void layout_element_scale(bitmap_t *dest, const bitmap_t *source, const r in the specified color -------------------------------------------------*/ -static void layout_element_draw_rect(bitmap_t *dest, const rectangle *bounds, const render_color *color) +static void layout_element_draw_rect(bitmap_t &dest, const rectangle &bounds, const render_color &color) { UINT32 r, g, b, inva; UINT32 x, y; /* compute premultiplied colors */ - r = color->r * color->a * 255.0; - g = color->g * color->a * 255.0; - b = color->b * color->a * 255.0; - inva = (1.0f - color->a) * 255.0; + r = color.r * color.a * 255.0; + g = color.g * color.a * 255.0; + b = color.b * color.a * 255.0; + inva = (1.0f - color.a) * 255.0; /* iterate over X and Y */ - for (y = bounds->min_y; y < bounds->max_y; y++) - for (x = bounds->min_x; x < bounds->max_x; x++) + for (y = bounds.min_y; y < bounds.max_y; y++) + for (x = bounds.min_x; x < bounds.max_x; x++) { UINT32 finalr = r; UINT32 finalg = g; @@ -449,14 +449,14 @@ static void layout_element_draw_rect(bitmap_t *dest, const rectangle *bounds, co /* if we're translucent, add in the destination pixel contribution */ if (inva > 0) { - UINT32 dpix = *BITMAP_ADDR32(dest, y, x); + UINT32 dpix = *BITMAP_ADDR32(&dest, y, x); finalr += (RGB_RED(dpix) * inva) >> 8; finalg += (RGB_GREEN(dpix) * inva) >> 8; finalb += (RGB_BLUE(dpix) * inva) >> 8; } /* store the target pixel, dividing the RGBA values by the overall scale factor */ - *BITMAP_ADDR32(dest, y, x) = MAKE_ARGB(0xff, finalr, finalg, finalb); + *BITMAP_ADDR32(&dest, y, x) = MAKE_ARGB(0xff, finalr, finalg, finalb); } } @@ -466,7 +466,7 @@ static void layout_element_draw_rect(bitmap_t *dest, const rectangle *bounds, co in the specified color -------------------------------------------------*/ -static void layout_element_draw_disk(bitmap_t *dest, const rectangle *bounds, const render_color *color) +static void layout_element_draw_disk(bitmap_t &dest, const rectangle &bounds, const render_color &color) { float xcenter, ycenter; float xradius, yradius, ooyradius2; @@ -474,20 +474,20 @@ static void layout_element_draw_disk(bitmap_t *dest, const rectangle *bounds, co UINT32 x, y; /* compute premultiplied colors */ - r = color->r * color->a * 255.0; - g = color->g * color->a * 255.0; - b = color->b * color->a * 255.0; - inva = (1.0f - color->a) * 255.0; + r = color.r * color.a * 255.0; + g = color.g * color.a * 255.0; + b = color.b * color.a * 255.0; + inva = (1.0f - color.a) * 255.0; /* find the center */ - xcenter = (float)(bounds->min_x + bounds->max_x) * 0.5f; - ycenter = (float)(bounds->min_y + bounds->max_y) * 0.5f; - xradius = (float)(bounds->max_x - bounds->min_x) * 0.5f; - yradius = (float)(bounds->max_y - bounds->min_y) * 0.5f; + xcenter = (float)(bounds.min_x + bounds.max_x) * 0.5f; + ycenter = (float)(bounds.min_y + bounds.max_y) * 0.5f; + xradius = (float)(bounds.max_x - bounds.min_x) * 0.5f; + yradius = (float)(bounds.max_y - bounds.min_y) * 0.5f; ooyradius2 = 1.0f / (yradius * yradius); /* iterate over y */ - for (y = bounds->min_y; y < bounds->max_y; y++) + for (y = bounds.min_y; y < bounds.max_y; y++) { float ycoord = ycenter - ((float)y + 0.5f); float xval = xradius * sqrt(1.0f - (ycoord * ycoord) * ooyradius2); @@ -507,14 +507,14 @@ static void layout_element_draw_disk(bitmap_t *dest, const rectangle *bounds, co /* if we're translucent, add in the destination pixel contribution */ if (inva > 0) { - UINT32 dpix = *BITMAP_ADDR32(dest, y, x); + UINT32 dpix = *BITMAP_ADDR32(&dest, y, x); finalr += (RGB_RED(dpix) * inva) >> 8; finalg += (RGB_GREEN(dpix) * inva) >> 8; finalb += (RGB_BLUE(dpix) * inva) >> 8; } /* store the target pixel, dividing the RGBA values by the overall scale factor */ - *BITMAP_ADDR32(dest, y, x) = MAKE_ARGB(0xff, finalr, finalg, finalb); + *BITMAP_ADDR32(&dest, y, x) = MAKE_ARGB(0xff, finalr, finalg, finalb); } } } @@ -525,9 +525,9 @@ static void layout_element_draw_disk(bitmap_t *dest, const rectangle *bounds, co specified color -------------------------------------------------*/ -static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, const render_color *color, const char *string) +static void layout_element_draw_text(running_machine &machine, bitmap_t &dest, const rectangle &bounds, const render_color &color, const char *string) { - render_font *font = render_font_alloc(NULL); + render_font *font = render_font_alloc(machine, NULL); bitmap_t *tempbitmap; UINT32 r, g, b, a; float aspect = 1.0f; @@ -535,23 +535,23 @@ static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, co const char *s; /* compute premultiplied colors */ - r = color->r * 255.0; - g = color->g * 255.0; - b = color->b * 255.0; - a = color->a * 255.0; + r = color.r * 255.0; + g = color.g * 255.0; + b = color.b * 255.0; + a = color.a * 255.0; /* get the width of the string */ while (1) { - width = render_font_get_string_width(font, bounds->max_y - bounds->min_y, aspect, string); - if (width < bounds->max_x - bounds->min_x) + width = render_font_get_string_width(font, bounds.max_y - bounds.min_y, aspect, string); + if (width < bounds.max_x - bounds.min_x) break; aspect *= 0.9f; } - curx = bounds->min_x + (bounds->max_x - bounds->min_x - width) / 2; + curx = bounds.min_x + (bounds.max_x - bounds.min_x - width) / 2; /* allocate a temporary bitmap */ - tempbitmap = global_alloc(bitmap_t(dest->width, dest->height, BITMAP_FORMAT_ARGB32)); + tempbitmap = global_alloc(bitmap_t(dest.width, dest.height, BITMAP_FORMAT_ARGB32)); /* loop over characters */ for (s = string; *s != 0; s++) @@ -560,20 +560,20 @@ static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, co int x, y; /* get the font bitmap */ - render_font_get_scaled_bitmap_and_bounds(font, tempbitmap, bounds->max_y - bounds->min_y, aspect, *s, &chbounds); + render_font_get_scaled_bitmap_and_bounds(font, tempbitmap, bounds.max_y - bounds.min_y, aspect, *s, &chbounds); /* copy the data into the target */ for (y = 0; y < chbounds.max_y - chbounds.min_y; y++) { - int effy = bounds->min_y + y; - if (effy >= bounds->min_y && effy <= bounds->max_y) + int effy = bounds.min_y + y; + if (effy >= bounds.min_y && effy <= bounds.max_y) { UINT32 *src = BITMAP_ADDR32(tempbitmap, y, 0); - UINT32 *d = BITMAP_ADDR32(dest, effy, 0); + UINT32 *d = BITMAP_ADDR32(&dest, effy, 0); for (x = 0; x < chbounds.max_x - chbounds.min_x; x++) { int effx = curx + x + chbounds.min_x; - if (effx >= bounds->min_x && effx <= bounds->max_x) + if (effx >= bounds.min_x && effx <= bounds.max_x) { UINT32 spix = RGB_ALPHA(src[x]); if (spix != 0) @@ -593,7 +593,7 @@ static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, co } /* advance in the X direction */ - curx += render_font_get_char_width(font, bounds->max_y - bounds->min_y, aspect, *s); + curx += render_font_get_char_width(font, bounds.max_y - bounds.min_y, aspect, *s); } /* free the temporary bitmap and font */ @@ -608,15 +608,15 @@ static void layout_element_draw_text(bitmap_t *dest, const rectangle *bounds, co and start points -------------------------------------------------*/ -static void draw_segment_horizontal_caps(bitmap_t *dest, int minx, int maxx, int midy, int width, int caps, rgb_t color) +static void draw_segment_horizontal_caps(bitmap_t &dest, int minx, int maxx, int midy, int width, int caps, rgb_t color) { int x, y; /* loop over the width of the segment */ for (y = 0; y < width / 2; y++) { - UINT32 *d0 = BITMAP_ADDR32(dest, midy - y, 0); - UINT32 *d1 = BITMAP_ADDR32(dest, midy + y, 0); + UINT32 *d0 = BITMAP_ADDR32(&dest, midy - y, 0); + UINT32 *d1 = BITMAP_ADDR32(&dest, midy + y, 0); int ty = (y < width / 8) ? width / 8 : y; /* loop over the length of the segment */ @@ -631,7 +631,7 @@ static void draw_segment_horizontal_caps(bitmap_t *dest, int minx, int maxx, int LED segment -------------------------------------------------*/ -static void draw_segment_horizontal(bitmap_t *dest, int minx, int maxx, int midy, int width, rgb_t color) +static void draw_segment_horizontal(bitmap_t &dest, int minx, int maxx, int midy, int width, rgb_t color) { draw_segment_horizontal_caps(dest, minx, maxx, midy, width, LINE_CAP_START | LINE_CAP_END, color); } @@ -643,20 +643,20 @@ static void draw_segment_horizontal(bitmap_t *dest, int minx, int maxx, int midy and start points -------------------------------------------------*/ -static void draw_segment_vertical_caps(bitmap_t *dest, int miny, int maxy, int midx, int width, int caps, rgb_t color) +static void draw_segment_vertical_caps(bitmap_t &dest, int miny, int maxy, int midx, int width, int caps, rgb_t color) { int x, y; /* loop over the width of the segment */ for (x = 0; x < width / 2; x++) { - UINT32 *d0 = BITMAP_ADDR32(dest, 0, midx - x); - UINT32 *d1 = BITMAP_ADDR32(dest, 0, midx + x); + UINT32 *d0 = BITMAP_ADDR32(&dest, 0, midx - x); + UINT32 *d1 = BITMAP_ADDR32(&dest, 0, midx + x); int tx = (x < width / 8) ? width / 8 : x; /* loop over the length of the segment */ for (y = miny + ((caps & LINE_CAP_START) ? tx : 0); y < maxy - ((caps & LINE_CAP_END) ? tx : 0); y++) - d0[y * dest->rowpixels] = d1[y * dest->rowpixels] = color; + d0[y * dest.rowpixels] = d1[y * dest.rowpixels] = color; } } @@ -666,7 +666,7 @@ static void draw_segment_vertical_caps(bitmap_t *dest, int miny, int maxy, int m LED segment -------------------------------------------------*/ -static void draw_segment_vertical(bitmap_t *dest, int miny, int maxy, int midx, int width, rgb_t color) +static void draw_segment_vertical(bitmap_t &dest, int miny, int maxy, int midx, int width, rgb_t color) { draw_segment_vertical_caps(dest, miny, maxy, midx, width, LINE_CAP_START | LINE_CAP_END, color); } @@ -677,7 +677,7 @@ static void draw_segment_vertical(bitmap_t *dest, int miny, int maxy, int midx, LED segment that looks like this: / -------------------------------------------------*/ -static void draw_segment_diagonal_1(bitmap_t *dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) +static void draw_segment_diagonal_1(bitmap_t &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) { int x, y; float ratio; @@ -688,15 +688,15 @@ static void draw_segment_diagonal_1(bitmap_t *dest, int minx, int maxx, int miny /* draw line */ for (x = minx; x < maxx; x++) - if (x >= 0 && x < dest->width) + if (x >= 0 && x < dest.width) { - UINT32 *d = BITMAP_ADDR32(dest, 0, x); + UINT32 *d = BITMAP_ADDR32(&dest, 0, x); int step = (x - minx) * ratio; for (y = maxy - width - step; y < maxy - step; y++) - if (y >= 0 && y < dest->height) + if (y >= 0 && y < dest.height) { - d[y * dest->rowpixels] = color; + d[y * dest.rowpixels] = color; } } } @@ -707,7 +707,7 @@ static void draw_segment_diagonal_1(bitmap_t *dest, int minx, int maxx, int miny LED segment that looks like this: \ -------------------------------------------------*/ -static void draw_segment_diagonal_2(bitmap_t *dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) +static void draw_segment_diagonal_2(bitmap_t &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) { int x, y; float ratio; @@ -718,15 +718,15 @@ static void draw_segment_diagonal_2(bitmap_t *dest, int minx, int maxx, int miny /* draw line */ for (x = minx; x < maxx; x++) - if (x >= 0 && x < dest->width) + if (x >= 0 && x < dest.width) { - UINT32 *d = BITMAP_ADDR32(dest, 0, x); + UINT32 *d = BITMAP_ADDR32(&dest, 0, x); int step = (x - minx) * ratio; for (y = miny + step; y < miny + step + width; y++) - if (y >= 0 && y < dest->height) + if (y >= 0 && y < dest.height) { - d[y * dest->rowpixels] = color; + d[y * dest.rowpixels] = color; } } } @@ -736,7 +736,7 @@ static void draw_segment_diagonal_2(bitmap_t *dest, int minx, int maxx, int miny draw_segment_decimal - draw a decimal point -------------------------------------------------*/ -static void draw_segment_decimal(bitmap_t *dest, int midx, int midy, int width, rgb_t color) +static void draw_segment_decimal(bitmap_t &dest, int midx, int midy, int width, rgb_t color) { float ooradius2; UINT32 x, y; @@ -748,8 +748,8 @@ static void draw_segment_decimal(bitmap_t *dest, int midx, int midy, int width, /* iterate over y */ for (y = 0; y <= width; y++) { - UINT32 *d0 = BITMAP_ADDR32(dest, midy - y, 0); - UINT32 *d1 = BITMAP_ADDR32(dest, midy + y, 0); + UINT32 *d0 = BITMAP_ADDR32(&dest, midy - y, 0); + UINT32 *d1 = BITMAP_ADDR32(&dest, midy + y, 0); float xval = width * sqrt(1.0f - (float)(y * y) * ooradius2); INT32 left, right; @@ -767,7 +767,7 @@ static void draw_segment_decimal(bitmap_t *dest, int midx, int midy, int width, draw_segment_comma - draw a comma tail -------------------------------------------------*/ #if 0 -static void draw_segment_comma(bitmap_t *dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) +static void draw_segment_comma(bitmap_t &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color) { int x, y; float ratio; @@ -779,12 +779,12 @@ static void draw_segment_comma(bitmap_t *dest, int minx, int maxx, int miny, int /* draw line */ for (x = minx; x < maxx; x++) { - UINT32 *d = BITMAP_ADDR32(dest, 0, x); + UINT32 *d = BITMAP_ADDR32(&dest, 0, x); int step = (x - minx) * ratio; for (y = maxy; y < maxy - width - step; y--) { - d[y * dest->rowpixels] = color; + d[y * dest.rowpixels] = color; } } } @@ -795,15 +795,15 @@ static void draw_segment_comma(bitmap_t *dest, int minx, int maxx, int miny, int apply_skew - apply skew to a bitmap_t -------------------------------------------------*/ -static void apply_skew(bitmap_t *dest, int skewwidth) +static void apply_skew(bitmap_t &dest, int skewwidth) { int x, y; - for (y = 0; y < dest->height; y++) + for (y = 0; y < dest.height; y++) { - UINT32 *destrow = BITMAP_ADDR32(dest, y, 0); - int offs = skewwidth * (dest->height - y) / dest->height; - for (x = dest->width - skewwidth - 1; x >= 0; x--) + UINT32 *destrow = BITMAP_ADDR32(&dest, y, 0); + int offs = skewwidth * (dest.height - y) / dest.height; + for (x = dest.width - skewwidth - 1; x >= 0; x--) destrow[x + offs] = destrow[x]; for (x = 0; x < offs; x++) destrow[x] = 0; @@ -816,7 +816,7 @@ static void apply_skew(bitmap_t *dest, int skewwidth) 7-segment LCD -------------------------------------------------*/ -static void layout_element_draw_led7seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_led7seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff,0xff,0xff,0xff); const rgb_t offpen = MAKE_ARGB(0xff,0x20,0x20,0x20); @@ -834,34 +834,34 @@ static void layout_element_draw_led7seg(bitmap_t *dest, const rectangle *bounds, bitmap_fill(tempbitmap, NULL, MAKE_ARGB(0xff,0x00,0x00,0x00)); /* top bar */ - draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 0)) ? onpen : offpen); + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 0)) ? onpen : offpen); /* top-right bar */ - draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 1)) ? onpen : offpen); + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 1)) ? onpen : offpen); /* bottom-right bar */ - draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); /* bottom bar */ - draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); /* bottom-left bar */ - draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 4)) ? onpen : offpen); + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 4)) ? onpen : offpen); /* top-left bar */ - draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 5)) ? onpen : offpen); + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 5)) ? onpen : offpen); /* middle bar */ - draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (pattern & (1 << 6)) ? onpen : offpen); + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (pattern & (1 << 6)) ? onpen : offpen); /* apply skew */ - apply_skew(tempbitmap, 40); + apply_skew(*tempbitmap, 40); /* decimal point */ - draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 7)) ? onpen : offpen); + draw_segment_decimal(*tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 7)) ? onpen : offpen); /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -872,7 +872,7 @@ static void layout_element_draw_led7seg(bitmap_t *dest, const rectangle *bounds, 14-segment LCD -------------------------------------------------*/ -static void layout_element_draw_led14seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_led14seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff); const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20); @@ -890,84 +890,84 @@ static void layout_element_draw_led14seg(bitmap_t *dest, const rectangle *bounds bitmap_fill(tempbitmap, NULL, MAKE_ARGB(0xff, 0x00, 0x00, 0x00)); /* top bar */ - draw_segment_horizontal(tempbitmap, + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 0)) ? onpen : offpen); /* right-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 1)) ? onpen : offpen); /* right-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); /* bottom bar */ - draw_segment_horizontal(tempbitmap, + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); /* left-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 4)) ? onpen : offpen); /* left-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 5)) ? onpen : offpen); /* horizontal-middle-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, segwidth, LINE_CAP_START, (pattern & (1 << 6)) ? onpen : offpen); /* horizontal-middle-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, segwidth, LINE_CAP_END, (pattern & (1 << 7)) ? onpen : offpen); /* vertical-middle-top bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 8)) ? onpen : offpen); /* vertical-middle-bottom bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 9)) ? onpen : offpen); /* diagonal-left-bottom bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 10)) ? onpen : offpen); /* diagonal-left-top bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 11)) ? onpen : offpen); /* diagonal-right-top bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 12)) ? onpen : offpen); /* diagonal-right-bottom bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 13)) ? onpen : offpen); /* apply skew */ - apply_skew(tempbitmap, 40); + apply_skew(*tempbitmap, 40); /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -978,7 +978,7 @@ static void layout_element_draw_led14seg(bitmap_t *dest, const rectangle *bounds 14-segment LCD with semicolon (2 extra segments) -------------------------------------------------*/ -static void layout_element_draw_led14segsc(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_led14segsc(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff); const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20); @@ -996,93 +996,93 @@ static void layout_element_draw_led14segsc(bitmap_t *dest, const rectangle *boun bitmap_fill(tempbitmap, NULL, MAKE_ARGB(0xff, 0x00, 0x00, 0x00)); /* top bar */ - draw_segment_horizontal(tempbitmap, + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 0)) ? onpen : offpen); /* right-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 1)) ? onpen : offpen); /* right-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); /* bottom bar */ - draw_segment_horizontal(tempbitmap, + draw_segment_horizontal(*tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); /* left-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 4)) ? onpen : offpen); /* left-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 5)) ? onpen : offpen); /* horizontal-middle-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, segwidth, LINE_CAP_START, (pattern & (1 << 6)) ? onpen : offpen); /* horizontal-middle-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, segwidth, LINE_CAP_END, (pattern & (1 << 7)) ? onpen : offpen); /* vertical-middle-top bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 8)) ? onpen : offpen); /* vertical-middle-bottom bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 9)) ? onpen : offpen); /* diagonal-left-bottom bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 10)) ? onpen : offpen); /* diagonal-left-top bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 11)) ? onpen : offpen); /* diagonal-right-top bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 12)) ? onpen : offpen); /* diagonal-right-bottom bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 13)) ? onpen : offpen); /* apply skew */ - apply_skew(tempbitmap, 40); + apply_skew(*tempbitmap, 40); /* decimal point */ - draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 14)) ? onpen : offpen); + draw_segment_decimal(*tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 14)) ? onpen : offpen); /* comma tail */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth - (segwidth/2), bmwidth + segwidth, bmheight - (segwidth), bmheight + segwidth*1.5, segwidth/2, (pattern & (1 << 15)) ? onpen : offpen); /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -1093,7 +1093,7 @@ static void layout_element_draw_led14segsc(bitmap_t *dest, const rectangle *boun 16-segment LCD -------------------------------------------------*/ -static void layout_element_draw_led16seg(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_led16seg(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff); const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20); @@ -1111,94 +1111,94 @@ static void layout_element_draw_led16seg(bitmap_t *dest, const rectangle *bounds bitmap_fill(tempbitmap, NULL, MAKE_ARGB(0xff, 0x00, 0x00, 0x00)); /* top-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2, segwidth, LINE_CAP_START, (pattern & (1 << 0)) ? onpen : offpen); /* top-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, LINE_CAP_END, (pattern & (1 << 1)) ? onpen : offpen); /* right-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); /* right-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); /* bottom-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, LINE_CAP_END, (pattern & (1 << 4)) ? onpen : offpen); /* bottom-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2, segwidth, LINE_CAP_START, (pattern & (1 << 5)) ? onpen : offpen); /* left-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 6)) ? onpen : offpen); /* left-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 7)) ? onpen : offpen); /* horizontal-middle-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, segwidth, LINE_CAP_START, (pattern & (1 << 8)) ? onpen : offpen); /* horizontal-middle-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, segwidth, LINE_CAP_END, (pattern & (1 << 9)) ? onpen : offpen); /* vertical-middle-top bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 10)) ? onpen : offpen); /* vertical-middle-bottom bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 11)) ? onpen : offpen); /* diagonal-left-bottom bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 12)) ? onpen : offpen); /* diagonal-left-top bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 13)) ? onpen : offpen); /* diagonal-right-top bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 14)) ? onpen : offpen); /* diagonal-right-bottom bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 15)) ? onpen : offpen); /* apply skew */ - apply_skew(tempbitmap, 40); + apply_skew(*tempbitmap, 40); /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -1209,7 +1209,7 @@ static void layout_element_draw_led16seg(bitmap_t *dest, const rectangle *bounds 16-segment LCD with semicolon (2 extra segments) -------------------------------------------------*/ -static void layout_element_draw_led16segsc(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_led16segsc(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff); const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20); @@ -1227,103 +1227,103 @@ static void layout_element_draw_led16segsc(bitmap_t *dest, const rectangle *boun bitmap_fill(tempbitmap, NULL, MAKE_ARGB(0xff, 0x00, 0x00, 0x00)); /* top-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2, segwidth, LINE_CAP_START, (pattern & (1 << 0)) ? onpen : offpen); /* top-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, LINE_CAP_END, (pattern & (1 << 1)) ? onpen : offpen); /* right-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 2)) ? onpen : offpen); /* right-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (pattern & (1 << 3)) ? onpen : offpen); /* bottom-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, LINE_CAP_END, (pattern & (1 << 4)) ? onpen : offpen); /* bottom-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2, segwidth, LINE_CAP_START, (pattern & (1 << 5)) ? onpen : offpen); /* left-bottom bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 6)) ? onpen : offpen); /* left-top bar */ - draw_segment_vertical(tempbitmap, + draw_segment_vertical(*tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (pattern & (1 << 7)) ? onpen : offpen); /* horizontal-middle-left bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, segwidth, LINE_CAP_START, (pattern & (1 << 8)) ? onpen : offpen); /* horizontal-middle-right bar */ - draw_segment_horizontal_caps(tempbitmap, + draw_segment_horizontal_caps(*tempbitmap, 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, segwidth, LINE_CAP_END, (pattern & (1 << 9)) ? onpen : offpen); /* vertical-middle-top bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 10)) ? onpen : offpen); /* vertical-middle-bottom bar */ - draw_segment_vertical_caps(tempbitmap, + draw_segment_vertical_caps(*tempbitmap, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, segwidth, LINE_CAP_NONE, (pattern & (1 << 11)) ? onpen : offpen); /* diagonal-left-bottom bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 12)) ? onpen : offpen); /* diagonal-left-top bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 13)) ? onpen : offpen); /* diagonal-right-top bar */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, segwidth, (pattern & (1 << 14)) ? onpen : offpen); /* diagonal-right-bottom bar */ - draw_segment_diagonal_2(tempbitmap, + draw_segment_diagonal_2(*tempbitmap, bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, segwidth, (pattern & (1 << 15)) ? onpen : offpen); /* decimal point */ - draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 16)) ? onpen : offpen); + draw_segment_decimal(*tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (pattern & (1 << 16)) ? onpen : offpen); /* comma tail */ - draw_segment_diagonal_1(tempbitmap, + draw_segment_diagonal_1(*tempbitmap, bmwidth - (segwidth/2), bmwidth + segwidth, bmheight - (segwidth), bmheight + segwidth*1.5, segwidth/2, (pattern & (1 << 17)) ? onpen : offpen); /* apply skew */ - apply_skew(tempbitmap, 40); + apply_skew(*tempbitmap, 40); /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -1333,7 +1333,7 @@ static void layout_element_draw_led16segsc(bitmap_t *dest, const rectangle *boun row of 8 dots for a dotmatrix -------------------------------------------------*/ -static void layout_element_draw_dotmatrix(bitmap_t *dest, const rectangle *bounds, const render_color *color, int pattern) +static void layout_element_draw_dotmatrix(bitmap_t &dest, const rectangle &bounds, const render_color &color, int pattern) { const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff); const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20); @@ -1351,11 +1351,11 @@ static void layout_element_draw_dotmatrix(bitmap_t *dest, const rectangle *bound for (i = 0; i < 8; i++) {// height - draw_segment_decimal(tempbitmap, ((dotwidth/2 )+ (i * dotwidth)), bmheight/2, dotwidth, (pattern & (1 << i))?onpen:offpen); + draw_segment_decimal(*tempbitmap, ((dotwidth/2 )+ (i * dotwidth)), bmheight/2, dotwidth, (pattern & (1 << i))?onpen:offpen); } /* resample to the target size */ - render_resample_argb_bitmap_hq(dest->base, dest->rowpixels, dest->width, dest->height, tempbitmap, NULL, color); + render_resample_argb_bitmap_hq(dest.base, dest.rowpixels, dest.width, dest.height, tempbitmap, NULL, &color); global_free(tempbitmap); } @@ -1370,16 +1370,16 @@ static void layout_element_draw_dotmatrix(bitmap_t *dest, const rectangle *bound a variable in an XML attribute -------------------------------------------------*/ -static int get_variable_value(const machine_config *config, const char *string, char **outputptr) +static int get_variable_value(running_machine &machine, const char *string, char **outputptr) { const screen_device_config *devconfig; int num, den; char temp[100]; /* screen 0 parameters */ - for (devconfig = screen_first(*config); devconfig != NULL; devconfig = screen_next(devconfig)) + for (devconfig = screen_first(machine.m_config); devconfig != NULL; devconfig = screen_next(devconfig)) { - int scrnum = config->m_devicelist.index(SCREEN, devconfig->tag()); + int scrnum = machine.m_config.m_devicelist.index(SCREEN, devconfig->tag()); /* native X aspect factor */ sprintf(temp, "~scr%dnativexaspect~", scrnum); @@ -1433,7 +1433,7 @@ static int get_variable_value(const machine_config *config, const char *string, substitution -------------------------------------------------*/ -static const char *xml_get_attribute_string_with_subst(const machine_config *config, xml_data_node *node, const char *attribute, const char *defvalue) +static const char *xml_get_attribute_string_with_subst(running_machine &machine, xml_data_node *node, const char *attribute, const char *defvalue) { const char *str = xml_get_attribute_string(node, attribute, NULL); static char buffer[1000]; @@ -1457,7 +1457,7 @@ static const char *xml_get_attribute_string_with_subst(const machine_config *con /* extract the variable */ else - s += get_variable_value(config, s, &d); + s += get_variable_value(machine, s, &d); } *d = 0; return buffer; @@ -1470,9 +1470,9 @@ static const char *xml_get_attribute_string_with_subst(const machine_config *con substitution -------------------------------------------------*/ -static int xml_get_attribute_int_with_subst(const machine_config *config, xml_data_node *node, const char *attribute, int defvalue) +static int xml_get_attribute_int_with_subst(running_machine &machine, xml_data_node *node, const char *attribute, int defvalue) { - const char *string = xml_get_attribute_string_with_subst(config, node, attribute, NULL); + const char *string = xml_get_attribute_string_with_subst(machine, node, attribute, NULL); int value; if (string == NULL) @@ -1493,9 +1493,9 @@ static int xml_get_attribute_int_with_subst(const machine_config *config, xml_da substitution -------------------------------------------------*/ -static float xml_get_attribute_float_with_subst(const machine_config *config, xml_data_node *node, const char *attribute, float defvalue) +static float xml_get_attribute_float_with_subst(running_machine &machine, xml_data_node *node, const char *attribute, float defvalue) { - const char *string = xml_get_attribute_string_with_subst(config, node, attribute, NULL); + const char *string = xml_get_attribute_string_with_subst(machine, node, attribute, NULL); float value; if (!string || sscanf(string, "%f", &value) != 1) @@ -1509,7 +1509,7 @@ static float xml_get_attribute_float_with_subst(const machine_config *config, xm into a layout_file -------------------------------------------------*/ -layout_file *layout_file_load(const machine_config *config, const char *dirname, const char *filename) +layout_file *layout_file_load(running_machine &machine, const char *dirname, const char *filename) { xml_data_node *rootnode, *mamelayoutnode, *elemnode, *viewnode; layout_element **elemnext; @@ -1561,7 +1561,7 @@ layout_file *layout_file_load(const machine_config *config, const char *dirname, elemnext = &file->elemlist; for (elemnode = xml_get_sibling(mamelayoutnode->child, "element"); elemnode; elemnode = xml_get_sibling(elemnode->next, "element")) { - layout_element *element = load_layout_element(config, elemnode, dirname); + layout_element *element = load_layout_element(machine, elemnode, dirname); if (element == NULL) goto error; @@ -1575,7 +1575,7 @@ layout_file *layout_file_load(const machine_config *config, const char *dirname, viewnext = &file->viewlist; for (viewnode = xml_get_sibling(mamelayoutnode->child, "view"); viewnode; viewnode = xml_get_sibling(viewnode->next, "view")) { - layout_view *view = load_layout_view(config, viewnode, file->elemlist); + layout_view *view = load_layout_view(machine, viewnode, file->elemlist); if (view == NULL) goto error; @@ -1599,7 +1599,7 @@ error: node from the layout file -------------------------------------------------*/ -static layout_element *load_layout_element(const machine_config *config, xml_data_node *elemnode, const char *dirname) +static layout_element *load_layout_element(running_machine &machine, xml_data_node *elemnode, const char *dirname) { render_bounds bounds = { 0 }; element_component **nextcomp; @@ -1616,14 +1616,15 @@ static layout_element *load_layout_element(const machine_config *config, xml_dat element = global_alloc_clear(layout_element); /* extract the name */ - name = xml_get_attribute_string_with_subst(config, elemnode, "name", NULL); + name = xml_get_attribute_string_with_subst(machine, elemnode, "name", NULL); if (name == NULL) { logerror("All layout elements must have a name!\n"); goto error; } + element->machine = &machine; element->name = copy_string(name); - element->defstate = xml_get_attribute_int_with_subst(config, elemnode, "defstate", -1); + element->defstate = xml_get_attribute_int_with_subst(machine, elemnode, "defstate", -1); /* parse components in order */ first = TRUE; @@ -1631,7 +1632,7 @@ static layout_element *load_layout_element(const machine_config *config, xml_dat for (compnode = elemnode->child; compnode; compnode = compnode->next) { /* allocate a new component */ - element_component *new_component = load_element_component(config, compnode, dirname); + element_component *new_component = load_element_component(machine, compnode, dirname); if (new_component == NULL) goto error; @@ -1681,7 +1682,7 @@ static layout_element *load_layout_element(const machine_config *config, xml_dat { element->elemtex[state].element = element; element->elemtex[state].state = state; - element->elemtex[state].texture = render_texture_alloc(layout_element_scale, &element->elemtex[state]); + element->elemtex[state].texture = machine.render().texture_alloc(layout_element_scale, &element->elemtex[state]); } return element; @@ -1697,7 +1698,7 @@ error: XML node (image/rect/disk) -------------------------------------------------*/ -static element_component *load_element_component(const machine_config *config, xml_data_node *compnode, const char *dirname) +static element_component *load_element_component(running_machine &machine, xml_data_node *compnode, const char *dirname) { element_component *component; @@ -1705,17 +1706,17 @@ static element_component *load_element_component(const machine_config *config, x component = global_alloc_clear(element_component); /* fetch common data */ - component->state = xml_get_attribute_int_with_subst(config, compnode, "state", -1); - if (load_bounds(config, xml_get_sibling(compnode->child, "bounds"), &component->bounds)) + component->state = xml_get_attribute_int_with_subst(machine, compnode, "state", -1); + if (load_bounds(machine, xml_get_sibling(compnode->child, "bounds"), &component->bounds)) goto error; - if (load_color(config, xml_get_sibling(compnode->child, "color"), &component->color)) + if (load_color(machine, xml_get_sibling(compnode->child, "color"), &component->color)) goto error; /* image nodes */ if (strcmp(compnode->name, "image") == 0) { - const char *file = xml_get_attribute_string_with_subst(config, compnode, "file", NULL); - const char *afile = xml_get_attribute_string_with_subst(config, compnode, "alphafile", NULL); + const char *file = xml_get_attribute_string_with_subst(machine, compnode, "file", NULL); + const char *afile = xml_get_attribute_string_with_subst(machine, compnode, "alphafile", NULL); /* load and allocate the bitmap */ component->type = COMPONENT_TYPE_IMAGE; @@ -1727,7 +1728,7 @@ static element_component *load_element_component(const machine_config *config, x /* text nodes */ else if (strcmp(compnode->name, "text") == 0) { - const char *text = xml_get_attribute_string_with_subst(config, compnode, "string", ""); + const char *text = xml_get_attribute_string_with_subst(machine, compnode, "string", ""); char *string; /* allocate a copy of the string */ @@ -1785,7 +1786,7 @@ error: load_layout_view - parse a view XML node -------------------------------------------------*/ -static layout_view *load_layout_view(const machine_config *config, xml_data_node *viewnode, layout_element *elemlist) +static layout_view *load_layout_view(running_machine &machine, xml_data_node *viewnode, layout_element *elemlist) { xml_data_node *boundsnode; view_item **itemnext; @@ -1796,11 +1797,11 @@ static layout_view *load_layout_view(const machine_config *config, xml_data_node view = global_alloc_clear(layout_view); /* allocate a copy of the name */ - view->name = copy_string(xml_get_attribute_string_with_subst(config, viewnode, "name", "")); + view->name = copy_string(xml_get_attribute_string_with_subst(machine, viewnode, "name", "")); /* if we have a bounds item, load it */ boundsnode = xml_get_sibling(viewnode->child, "bounds"); - if (boundsnode != NULL && load_bounds(config, xml_get_sibling(boundsnode, "bounds"), &view->expbounds)) + if (boundsnode != NULL && load_bounds(machine, xml_get_sibling(boundsnode, "bounds"), &view->expbounds)) goto error; /* loop over all the layer types we support */ @@ -1816,7 +1817,7 @@ static layout_view *load_layout_view(const machine_config *config, xml_data_node /* parse all of the elements of that type */ for (itemnode = xml_get_sibling(viewnode->child, layer_node_name[layer]); itemnode; itemnode = xml_get_sibling(itemnode->next, layer_node_name[layer])) { - view_item *item = load_view_item(config, itemnode, elemlist); + view_item *item = load_view_item(machine, itemnode, elemlist); if (!item) goto error; @@ -1840,7 +1841,7 @@ error: load_view_item - parse an item XML node -------------------------------------------------*/ -static view_item *load_view_item(const machine_config *config, xml_data_node *itemnode, layout_element *elemlist) +static view_item *load_view_item(running_machine &machine, xml_data_node *itemnode, layout_element *elemlist) { view_item *item; const char *name; @@ -1849,13 +1850,13 @@ static view_item *load_view_item(const machine_config *config, xml_data_node *it item = global_alloc_clear(view_item); /* allocate a copy of the output name */ - item->output_name = copy_string(xml_get_attribute_string_with_subst(config, itemnode, "name", "")); + item->output_name = copy_string(xml_get_attribute_string_with_subst(machine, itemnode, "name", "")); /* allocate a copy of the input tag */ - item->input_tag = copy_string(xml_get_attribute_string_with_subst(config, itemnode, "inputtag", "")); + item->input_tag = copy_string(xml_get_attribute_string_with_subst(machine, itemnode, "inputtag", "")); /* find the associated element */ - name = xml_get_attribute_string_with_subst(config, itemnode, "element", NULL); + name = xml_get_attribute_string_with_subst(machine, itemnode, "element", NULL); if (name != NULL) { layout_element *element; @@ -1872,15 +1873,15 @@ static view_item *load_view_item(const machine_config *config, xml_data_node *it } /* fetch common data */ - item->index = xml_get_attribute_int_with_subst(config, itemnode, "index", -1); - item->input_mask = xml_get_attribute_int_with_subst(config, itemnode, "inputmask", 0); + item->index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1); + item->input_mask = xml_get_attribute_int_with_subst(machine, itemnode, "inputmask", 0); if (item->output_name[0] != 0 && item->element != 0) output_set_value(item->output_name, item->element->defstate); - if (load_bounds(config, xml_get_sibling(itemnode->child, "bounds"), &item->rawbounds)) + if (load_bounds(machine, xml_get_sibling(itemnode->child, "bounds"), &item->rawbounds)) goto error; - if (load_color(config, xml_get_sibling(itemnode->child, "color"), &item->color)) + if (load_color(machine, xml_get_sibling(itemnode->child, "color"), &item->color)) goto error; - if (load_orientation(config, xml_get_sibling(itemnode->child, "orientation"), &item->orientation)) + if (load_orientation(machine, xml_get_sibling(itemnode->child, "orientation"), &item->orientation)) goto error; /* sanity checks */ @@ -1954,7 +1955,7 @@ static bitmap_t *load_component_bitmap(const char *dirname, const char *file, co load_bounds - parse a bounds XML node -------------------------------------------------*/ -static int load_bounds(const machine_config *config, xml_data_node *boundsnode, render_bounds *bounds) +static int load_bounds(running_machine &machine, xml_data_node *boundsnode, render_bounds *bounds) { /* skip if nothing */ if (boundsnode == NULL) @@ -1968,18 +1969,18 @@ static int load_bounds(const machine_config *config, xml_data_node *boundsnode, if (xml_get_attribute(boundsnode, "left") != NULL) { /* left/right/top/bottom format */ - bounds->x0 = xml_get_attribute_float_with_subst(config, boundsnode, "left", 0.0f); - bounds->x1 = xml_get_attribute_float_with_subst(config, boundsnode, "right", 1.0f); - bounds->y0 = xml_get_attribute_float_with_subst(config, boundsnode, "top", 0.0f); - bounds->y1 = xml_get_attribute_float_with_subst(config, boundsnode, "bottom", 1.0f); + bounds->x0 = xml_get_attribute_float_with_subst(machine, boundsnode, "left", 0.0f); + bounds->x1 = xml_get_attribute_float_with_subst(machine, boundsnode, "right", 1.0f); + bounds->y0 = xml_get_attribute_float_with_subst(machine, boundsnode, "top", 0.0f); + bounds->y1 = xml_get_attribute_float_with_subst(machine, boundsnode, "bottom", 1.0f); } else if (xml_get_attribute(boundsnode, "x") != NULL) { /* x/y/width/height format */ - bounds->x0 = xml_get_attribute_float_with_subst(config, boundsnode, "x", 0.0f); - bounds->x1 = bounds->x0 + xml_get_attribute_float_with_subst(config, boundsnode, "width", 1.0f); - bounds->y0 = xml_get_attribute_float_with_subst(config, boundsnode, "y", 0.0f); - bounds->y1 = bounds->y0 + xml_get_attribute_float_with_subst(config, boundsnode, "height", 1.0f); + bounds->x0 = xml_get_attribute_float_with_subst(machine, boundsnode, "x", 0.0f); + bounds->x1 = bounds->x0 + xml_get_attribute_float_with_subst(machine, boundsnode, "width", 1.0f); + bounds->y0 = xml_get_attribute_float_with_subst(machine, boundsnode, "y", 0.0f); + bounds->y1 = bounds->y0 + xml_get_attribute_float_with_subst(machine, boundsnode, "height", 1.0f); } else { @@ -2001,7 +2002,7 @@ static int load_bounds(const machine_config *config, xml_data_node *boundsnode, load_color - parse a color XML node -------------------------------------------------*/ -static int load_color(const machine_config *config, xml_data_node *colornode, render_color *color) +static int load_color(running_machine &machine, xml_data_node *colornode, render_color *color) { /* skip if nothing */ if (colornode == NULL) @@ -2011,10 +2012,10 @@ static int load_color(const machine_config *config, xml_data_node *colornode, re } /* parse out the data */ - color->r = xml_get_attribute_float_with_subst(config, colornode, "red", 1.0); - color->g = xml_get_attribute_float_with_subst(config, colornode, "green", 1.0); - color->b = xml_get_attribute_float_with_subst(config, colornode, "blue", 1.0); - color->a = xml_get_attribute_float_with_subst(config, colornode, "alpha", 1.0); + color->r = xml_get_attribute_float_with_subst(machine, colornode, "red", 1.0); + color->g = xml_get_attribute_float_with_subst(machine, colornode, "green", 1.0); + color->b = xml_get_attribute_float_with_subst(machine, colornode, "blue", 1.0); + color->a = xml_get_attribute_float_with_subst(machine, colornode, "alpha", 1.0); /* check for errors */ if (color->r < 0.0 || color->r > 1.0 || color->g < 0.0 || color->g > 1.0 || @@ -2032,7 +2033,7 @@ static int load_color(const machine_config *config, xml_data_node *colornode, re node -------------------------------------------------*/ -static int load_orientation(const machine_config *config, xml_data_node *orientnode, int *orientation) +static int load_orientation(running_machine &machine, xml_data_node *orientnode, int *orientation) { int rotate; @@ -2044,7 +2045,7 @@ static int load_orientation(const machine_config *config, xml_data_node *orientn } /* parse out the data */ - rotate = xml_get_attribute_int_with_subst(config, orientnode, "rotate", 0); + rotate = xml_get_attribute_int_with_subst(machine, orientnode, "rotate", 0); switch (rotate) { case 0: *orientation = ROT0; break; @@ -2055,11 +2056,11 @@ static int load_orientation(const machine_config *config, xml_data_node *orientn fatalerror("Invalid rotation in XML orientation node: %d", rotate); return 1; } - if (strcmp("yes", xml_get_attribute_string_with_subst(config, orientnode, "swapxy", "no")) == 0) + if (strcmp("yes", xml_get_attribute_string_with_subst(machine, orientnode, "swapxy", "no")) == 0) *orientation ^= ORIENTATION_SWAP_XY; - if (strcmp("yes", xml_get_attribute_string_with_subst(config, orientnode, "flipx", "no")) == 0) + if (strcmp("yes", xml_get_attribute_string_with_subst(machine, orientnode, "flipx", "no")) == 0) *orientation ^= ORIENTATION_FLIP_X; - if (strcmp("yes", xml_get_attribute_string_with_subst(config, orientnode, "flipy", "no")) == 0) + if (strcmp("yes", xml_get_attribute_string_with_subst(machine, orientnode, "flipy", "no")) == 0) *orientation ^= ORIENTATION_FLIP_Y; return 0; } @@ -2153,8 +2154,7 @@ static void layout_element_free(layout_element *element) /* loop over all states and free their textures */ for (state = 0; state <= element->maxstate; state++) - if (element->elemtex[state].texture != NULL) - render_texture_free(element->elemtex[state].texture); + element->machine->render().texture_free(element->elemtex[state].texture); global_free(element->elemtex); } diff --git a/src/emu/rendlay.h b/src/emu/rendlay.h index 64592fc6d1d..1a040c85f10 100644 --- a/src/emu/rendlay.h +++ b/src/emu/rendlay.h @@ -96,6 +96,7 @@ struct _element_texture struct _layout_element { layout_element * next; /* link to next element */ + running_machine * machine; const char * name; /* name of this element */ element_component * complist; /* head of the list of components */ int defstate; /* default state of this element */ @@ -164,7 +165,7 @@ void layout_view_recompute(layout_view *view, int layerconfig); /* ----- layout file parsing ----- */ -layout_file *layout_file_load(const machine_config *config, const char *dirname, const char *filename); +layout_file *layout_file_load(running_machine &machine, const char *dirname, const char *filename); void layout_file_free(layout_file *file); diff --git a/src/emu/softlist.c b/src/emu/softlist.c index 67f324c1b13..43b37595f9e 100644 --- a/src/emu/softlist.c +++ b/src/emu/softlist.c @@ -1455,7 +1455,7 @@ void ui_image_menu_software(running_machine *machine, ui_menu *menu, void *param if (event != NULL && event->iptkey == IPT_UI_SELECT) { - ui_menu *child_menu = ui_menu_alloc(machine, render_container_get_ui(), ui_mess_menu_software_list, NULL); + ui_menu *child_menu = ui_menu_alloc(machine, &machine->render().ui_container(), ui_mess_menu_software_list, NULL); software_menu_state *child_menustate = (software_menu_state *)ui_menu_alloc_state(child_menu, sizeof(*child_menustate), NULL); child_menustate->list_name = (char *)event->itemref; child_menustate->image = image; diff --git a/src/emu/ui.c b/src/emu/ui.c index db551a63cd5..872b34b43fe 100644 --- a/src/emu/ui.c +++ b/src/emu/ui.c @@ -240,7 +240,7 @@ int ui_init(running_machine *machine) machine->add_notifier(MACHINE_NOTIFY_EXIT, ui_exit); /* allocate the font and messagebox string */ - ui_font = render_font_alloc("ui.bdf"); + ui_font = render_font_alloc(*machine, "ui.bdf"); /* initialize the other UI bits */ ui_menu_init(machine); @@ -374,7 +374,7 @@ void ui_set_startup_text(running_machine *machine, const char *text, int force) void ui_update_and_render(running_machine *machine, render_container *container) { /* always start clean */ - render_container_empty(container); + container->empty(); /* if we're paused, dim the whole screen */ if (machine->phase() >= MACHINE_PHASE_RESET && (single_step || machine->paused())) @@ -385,7 +385,7 @@ void ui_update_and_render(running_machine *machine, render_container *container) if (alpha > 255) alpha = 255; if (alpha >= 0) - render_container_add_rect(container, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(alpha,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_rect(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(alpha,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } /* render any cheat stuff at the bottom */ @@ -422,17 +422,14 @@ render_font *ui_get_font(void) of a line -------------------------------------------------*/ -float ui_get_line_height(void) +float ui_get_line_height(running_machine &machine) { INT32 raw_font_pixel_height = render_font_get_pixel_height(ui_font); - INT32 target_pixel_width, target_pixel_height; + render_target &ui_target = machine.render().ui_target(); + INT32 target_pixel_height = ui_target.height(); float one_to_one_line_height; - float target_aspect; float scale_factor; - /* get info about the UI target */ - render_target_get_bounds(render_get_ui_target(), &target_pixel_width, &target_pixel_height, &target_aspect); - /* compute the font pixel height at the nominal size */ one_to_one_line_height = (float)raw_font_pixel_height / (float)target_pixel_height; @@ -470,9 +467,9 @@ float ui_get_line_height(void) single character -------------------------------------------------*/ -float ui_get_char_width(unicode_char ch) +float ui_get_char_width(running_machine &machine, unicode_char ch) { - return render_font_get_char_width(ui_font, ui_get_line_height(), render_get_ui_aspect(), ch); + return render_font_get_char_width(ui_font, ui_get_line_height(machine), machine.render().ui_aspect(), ch); } @@ -481,9 +478,9 @@ float ui_get_char_width(unicode_char ch) character string -------------------------------------------------*/ -float ui_get_string_width(const char *s) +float ui_get_string_width(running_machine &machine, const char *s) { - return render_font_get_utf8string_width(ui_font, ui_get_line_height(), render_get_ui_aspect(), s); + return render_font_get_utf8string_width(ui_font, ui_get_line_height(machine), machine.render().ui_aspect(), s); } @@ -495,11 +492,11 @@ float ui_get_string_width(const char *s) void ui_draw_outlined_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t backcolor) { - render_container_add_rect(container, x0, y0, x1, y1, backcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(container, x0, y0, x1, y0, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(container, x1, y0, x1, y1, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(container, x1, y1, x0, y1, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(container, x0, y1, x0, y0, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_rect(x0, y0, x1, y1, backcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_line(x0, y0, x1, y0, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_line(x1, y0, x1, y1, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_line(x1, y1, x0, y1, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_line(x0, y1, x0, y0, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } @@ -521,7 +518,8 @@ void ui_draw_text(render_container *container, const char *buf, float x, float y void ui_draw_text_full(render_container *container, const char *origs, float x, float y, float origwrapwidth, int justify, int wrap, int draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth, float *totalheight) { - float lineheight = ui_get_line_height(); + running_machine &machine = container->manager().machine(); + float lineheight = ui_get_line_height(machine); const char *ends = origs + strlen(origs); float wrapwidth = origwrapwidth; const char *s = origs; @@ -576,7 +574,7 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, break; /* get the width of this character */ - chwidth = ui_get_char_width(schar); + chwidth = ui_get_char_width(machine, schar); /* if we hit a space, remember the location and width *without* the space */ if (schar == ' ') @@ -620,7 +618,7 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, if (scharcount == -1) break; - curwidth -= ui_get_char_width(schar); + curwidth -= ui_get_char_width(machine, schar); } } @@ -628,7 +626,7 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, else if (wrap == WRAP_TRUNCATE) { /* add in the width of the ... */ - curwidth += 3.0f * ui_get_char_width('.'); + curwidth += 3.0f * ui_get_char_width(machine, '.'); /* while we are above the wrap width, back up one character */ while (curwidth > wrapwidth && s > linestart) @@ -639,7 +637,7 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, if (scharcount == -1) break; - curwidth -= ui_get_char_width(schar); + curwidth -= ui_get_char_width(machine, schar); } } } @@ -656,7 +654,7 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, /* if opaque, add a black box */ if (draw == DRAW_OPAQUE) - render_container_add_rect(container, curx, cury, curx + curwidth, cury + lineheight, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_rect(curx, cury, curx + curwidth, cury + lineheight, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* loop from the line start and add the characters */ while (linestart < s) @@ -669,8 +667,8 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, if (draw != DRAW_NONE) { - render_container_add_char(container, curx, cury, lineheight, render_get_ui_aspect(), fgcolor, ui_font, linechar); - curx += ui_get_char_width(linechar); + container->add_char(curx, cury, lineheight, machine.render().ui_aspect(), fgcolor, *ui_font, linechar); + curx += ui_get_char_width(machine, linechar); } linestart += linecharcount; } @@ -678,12 +676,12 @@ void ui_draw_text_full(render_container *container, const char *origs, float x, /* append ellipses if needed */ if (wrap == WRAP_TRUNCATE && *s != 0 && draw != DRAW_NONE) { - render_container_add_char(container, curx, cury, lineheight, render_get_ui_aspect(), fgcolor, ui_font, '.'); - curx += ui_get_char_width('.'); - render_container_add_char(container, curx, cury, lineheight, render_get_ui_aspect(), fgcolor, ui_font, '.'); - curx += ui_get_char_width('.'); - render_container_add_char(container, curx, cury, lineheight, render_get_ui_aspect(), fgcolor, ui_font, '.'); - curx += ui_get_char_width('.'); + container->add_char(curx, cury, lineheight, machine.render().ui_aspect(), fgcolor, *ui_font, '.'); + curx += ui_get_char_width(machine, '.'); + container->add_char(curx, cury, lineheight, machine.render().ui_aspect(), fgcolor, *ui_font, '.'); + curx += ui_get_char_width(machine, '.'); + container->add_char(curx, cury, lineheight, machine.render().ui_aspect(), fgcolor, *ui_font, '.'); + curx += ui_get_char_width(machine, '.'); } /* if we're not word-wrapping, we're done */ @@ -732,7 +730,7 @@ void ui_draw_text_box(render_container *container, const char *text, int justify ui_draw_text_full(container, text, 0, 0, 1.0f - 2.0f * UI_BOX_LR_BORDER, justify, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height); if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER) - target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / ui_get_line_height()) * ui_get_line_height(); + target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / ui_get_line_height(container->manager().machine())) * ui_get_line_height(container->manager().machine()); /* determine the target location */ target_x = xpos - 0.5f * target_width; @@ -1848,18 +1846,17 @@ static INT32 slider_refresh(running_machine *machine, void *arg, astring *string static INT32 slider_brightness(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.brightness = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_brightness = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.brightness); - return floor(settings.brightness * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_brightness); + return floor(settings.m_brightness * 1000.0f + 0.5f); } @@ -1871,18 +1868,17 @@ static INT32 slider_brightness(running_machine *machine, void *arg, astring *str static INT32 slider_contrast(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.contrast = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_contrast = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.contrast); - return floor(settings.contrast * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_contrast); + return floor(settings.m_contrast * 1000.0f + 0.5f); } @@ -1893,18 +1889,17 @@ static INT32 slider_contrast(running_machine *machine, void *arg, astring *strin static INT32 slider_gamma(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.gamma = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_gamma = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.gamma); - return floor(settings.gamma * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_gamma); + return floor(settings.m_gamma * 1000.0f + 0.5f); } @@ -1916,18 +1911,17 @@ static INT32 slider_gamma(running_machine *machine, void *arg, astring *string, static INT32 slider_xscale(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.xscale = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_xscale = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.xscale); - return floor(settings.xscale * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_xscale); + return floor(settings.m_xscale * 1000.0f + 0.5f); } @@ -1939,18 +1933,17 @@ static INT32 slider_xscale(running_machine *machine, void *arg, astring *string, static INT32 slider_yscale(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.yscale = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_yscale = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.yscale); - return floor(settings.yscale * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_yscale); + return floor(settings.m_yscale * 1000.0f + 0.5f); } @@ -1962,18 +1955,17 @@ static INT32 slider_yscale(running_machine *machine, void *arg, astring *string, static INT32 slider_xoffset(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.xoffset = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_xoffset = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.xoffset); - return floor(settings.xoffset * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_xoffset); + return floor(settings.m_xoffset * 1000.0f + 0.5f); } @@ -1985,18 +1977,17 @@ static INT32 slider_xoffset(running_machine *machine, void *arg, astring *string static INT32 slider_yoffset(running_machine *machine, void *arg, astring *string, INT32 newval) { screen_device *screen = reinterpret_cast(arg); - render_container *container = render_container_get_screen(screen); - render_container_user_settings settings; + render_container::user_settings settings; - render_container_get_user_settings(container, &settings); + screen->container().get_user_settings(settings); if (newval != SLIDER_NOCHANGE) { - settings.yoffset = (float)newval * 0.001f; - render_container_set_user_settings(container, &settings); + settings.m_yoffset = (float)newval * 0.001f; + screen->container().set_user_settings(settings); } if (string != NULL) - string->printf("%.3f", settings.yoffset); - return floor(settings.yoffset * 1000.0f + 0.5f); + string->printf("%.3f", settings.m_yoffset); + return floor(settings.m_yoffset * 1000.0f + 0.5f); } diff --git a/src/emu/ui.h b/src/emu/ui.h index 08d4730c7a4..679013649f9 100644 --- a/src/emu/ui.h +++ b/src/emu/ui.h @@ -136,11 +136,11 @@ void ui_update_and_render(running_machine *machine, render_container *container) render_font *ui_get_font(void); /* returns the line height of the font used by the UI system */ -float ui_get_line_height(void); +float ui_get_line_height(running_machine &machine); /* returns the width of a character or string in the UI font */ -float ui_get_char_width(unicode_char ch); -float ui_get_string_width(const char *s); +float ui_get_char_width(running_machine &machine, unicode_char ch); +float ui_get_string_width(running_machine &machine, const char *s); /* draw an outlined box filled with a given color */ void ui_draw_outlined_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t backcolor); diff --git a/src/emu/uigfx.c b/src/emu/uigfx.c index 3943d130b19..0e2f786ff4c 100644 --- a/src/emu/uigfx.c +++ b/src/emu/uigfx.c @@ -136,8 +136,7 @@ void ui_gfx_init(running_machine *machine) static void ui_gfx_exit(running_machine &machine) { /* free the texture */ - if (ui_gfx.texture != NULL) - render_texture_free(ui_gfx.texture); + machine.render().texture_free(ui_gfx.texture); ui_gfx.texture = NULL; /* free the bitmap */ @@ -253,8 +252,8 @@ static void palette_handler(running_machine *machine, render_container *containe int x, y, skip; /* add a half character padding for the box */ - chheight = ui_get_line_height(); - chwidth = render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), '0'); + chheight = ui_get_line_height(*machine); + chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; @@ -274,7 +273,7 @@ static void palette_handler(running_machine *machine, render_container *containe cellboxbounds.y0 += 3.0f * chheight; /* figure out the title and expand the outer box to fit */ - titlewidth = render_font_get_string_width(ui_font, chheight, render_get_ui_aspect(), title); + titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); @@ -287,8 +286,8 @@ static void palette_handler(running_machine *machine, render_container *containe y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { - render_container_add_char(container, x0, y0, chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, title[x]); - x0 += render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), title[x]); + container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]); + x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]); } /* compute the cell size */ @@ -301,12 +300,12 @@ static void palette_handler(running_machine *machine, render_container *containe { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; - render_container_add_char(container, x0 + 0.5f * (cellwidth - chwidth), y0, chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, "0123456789ABCDEF"[x & 0xf]); + container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, "0123456789ABCDEF"[x & 0xf]); /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ if (skip != 0) - render_container_add_point(container, x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + cellboxbounds.y0), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + cellboxbounds.y0), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } /* draw the side column headers */ @@ -323,14 +322,14 @@ static void palette_handler(running_machine *machine, render_container *containe x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) - render_container_add_point(container, 0.5f * (x0 + cellboxbounds.x0), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_point(0.5f * (x0 + cellboxbounds.x0), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the row header */ sprintf(buffer, "%5X", state->palette.offset + y * state->palette.count); for (x = 4; x >= 0; x--) { - x0 -= render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), buffer[x]); - render_container_add_char(container, x0, y0 + 0.5f * (cellheight - chheight), chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, buffer[x]); + x0 -= render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), buffer[x]); + container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]); } } @@ -342,7 +341,7 @@ static void palette_handler(running_machine *machine, render_container *containe if (index < total) { pen_t pen = state->palette.which ? colortable_palette_get_color(machine->colortable, index) : raw_color[index]; - render_container_add_rect(container, cellboxbounds.x0 + x * cellwidth, cellboxbounds.y0 + y * cellheight, + container->add_rect(cellboxbounds.x0 + x * cellwidth, cellboxbounds.y0 + y * cellheight, cellboxbounds.x0 + (x + 1) * cellwidth, cellboxbounds.y0 + (y + 1) * cellheight, 0xff000000 | pen, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } @@ -440,19 +439,17 @@ static void gfxset_handler(running_machine *machine, render_container *container render_bounds cellboxbounds; render_bounds boxbounds; int cellboxwidth, cellboxheight; - int targwidth, targheight; + int targwidth = machine->render().ui_target().width(); + int targheight = machine->render().ui_target().height(); int cellxpix, cellypix; int xcells, ycells; int pixelscale = 0; int x, y, skip; char title[100]; - /* get the bounds of our target */ - render_target_get_bounds(render_get_ui_target(), &targwidth, &targheight, NULL); - /* add a half character padding for the box */ - chheight = ui_get_line_height(); - chwidth = render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), '0'); + chheight = ui_get_line_height(*machine); + chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; @@ -517,7 +514,7 @@ static void gfxset_handler(running_machine *machine, render_container *container /* figure out the title and expand the outer box to fit */ for (x = 0; x < MAX_GFX_ELEMENTS && machine->gfx[x] != NULL; x++) ; sprintf(title, "GFX %d/%d %dx%d COLOR %X", state->gfxset.set, x - 1, gfx->width, gfx->height, state->gfxset.color[set]); - titlewidth = render_font_get_string_width(ui_font, chheight, render_get_ui_aspect(), title); + titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); @@ -530,8 +527,8 @@ static void gfxset_handler(running_machine *machine, render_container *container y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { - render_container_add_char(container, x0, y0, chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, title[x]); - x0 += render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), title[x]); + container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]); + x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]); } /* draw the top column headers */ @@ -540,12 +537,12 @@ static void gfxset_handler(running_machine *machine, render_container *container { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; - render_container_add_char(container, x0 + 0.5f * (cellwidth - chwidth), y0, chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, "0123456789ABCDEF"[x & 0xf]); + container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, "0123456789ABCDEF"[x & 0xf]); /* if we're skipping, draw a point between the character and the box to indicate which */ /* one it's referring to */ if (skip != 0) - render_container_add_point(container, x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + boxbounds.y0 + 3.5f * chheight), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + boxbounds.y0 + 3.5f * chheight), UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } /* draw the side column headers */ @@ -562,14 +559,14 @@ static void gfxset_handler(running_machine *machine, render_container *container x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) - render_container_add_point(container, 0.5f * (x0 + boxbounds.x0 + 6.0f * chwidth), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + container->add_point(0.5f * (x0 + boxbounds.x0 + 6.0f * chwidth), y0 + 0.5f * cellheight, UI_LINE_WIDTH, ARGB_WHITE, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the row header */ sprintf(buffer, "%5X", state->gfxset.offset[set] + y * xcells); for (x = 4; x >= 0; x--) { - x0 -= render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), buffer[x]); - render_container_add_char(container, x0, y0 + 0.5f * (cellheight - chheight), chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, buffer[x]); + x0 -= render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), buffer[x]); + container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, buffer[x]); } } @@ -577,7 +574,7 @@ static void gfxset_handler(running_machine *machine, render_container *container gfxset_update_bitmap(machine, state, xcells, ycells, gfx); /* add the final quad */ - render_container_add_quad(container, boxbounds.x0 + 6.0f * chwidth, boxbounds.y0 + 3.5f * chheight, + container->add_quad(boxbounds.x0 + 6.0f * chwidth, boxbounds.y0 + 3.5f * chheight, boxbounds.x0 + 6.0f * chwidth + (float)cellboxwidth / (float)targwidth, boxbounds.y0 + 3.5f * chheight + (float)cellboxheight / (float)targheight, ARGB_WHITE, state->texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); @@ -699,14 +696,13 @@ static void gfxset_update_bitmap(running_machine *machine, ui_gfx_state *state, if (state->bitmap == NULL || state->texture == NULL || state->bitmap->bpp != 32 || state->bitmap->width != cellxpix * xcells || state->bitmap->height != cellypix * ycells) { /* free the old stuff */ - if (state->texture != NULL) - render_texture_free(state->texture); + machine->render().texture_free(state->texture); global_free(state->bitmap); /* allocate new stuff */ state->bitmap = global_alloc(bitmap_t(cellxpix * xcells, cellypix * ycells, BITMAP_FORMAT_ARGB32)); - state->texture = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(state->texture, state->bitmap, NULL, TEXFORMAT_ARGB32, NULL); + state->texture = machine->render().texture_alloc(); + state->texture->set_bitmap(state->bitmap, NULL, TEXFORMAT_ARGB32); /* force a redraw */ state->bitmap_dirty = TRUE; @@ -754,7 +750,7 @@ static void gfxset_update_bitmap(running_machine *machine, ui_gfx_state *state, } /* reset the texture to force an update */ - render_texture_set_bitmap(state->texture, state->bitmap, NULL, TEXFORMAT_ARGB32, NULL); + state->texture->set_bitmap(state->bitmap, NULL, TEXFORMAT_ARGB32); state->bitmap_dirty = FALSE; } } @@ -848,7 +844,8 @@ static void tilemap_handler(running_machine *machine, render_container *containe float chwidth, chheight; render_bounds mapboxbounds; render_bounds boxbounds; - int targwidth, targheight; + int targwidth = machine->render().ui_target().width(); + int targheight = machine->render().ui_target().height(); float titlewidth; float x0, y0; int mapboxwidth, mapboxheight; @@ -857,17 +854,14 @@ static void tilemap_handler(running_machine *machine, render_container *containe int x, pixelscale; char title[100]; - /* get the bounds of our target */ - render_target_get_bounds(render_get_ui_target(), &targwidth, &targheight, NULL); - /* get the size of the tilemap itself */ tilemap_size_by_index(machine, state->tilemap.which, &mapwidth, &mapheight); if (state->tilemap.rotate & ORIENTATION_SWAP_XY) { UINT32 temp = mapwidth; mapwidth = mapheight; mapheight = temp; } /* add a half character padding for the box */ - chheight = ui_get_line_height(); - chwidth = render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), '0'); + chheight = ui_get_line_height(*machine); + chwidth = render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; @@ -914,7 +908,7 @@ static void tilemap_handler(running_machine *machine, render_container *containe /* figure out the title and expand the outer box to fit */ sprintf(title, "TMAP %d/%d %dx%d OFFS %d,%d", state->tilemap.which, tilemap_count(machine) - 1, mapwidth, mapheight, state->tilemap.xoffs, state->tilemap.yoffs); - titlewidth = render_font_get_string_width(ui_font, chheight, render_get_ui_aspect(), title); + titlewidth = render_font_get_string_width(ui_font, chheight, machine->render().ui_aspect(), title); if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) { boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth); @@ -929,15 +923,15 @@ static void tilemap_handler(running_machine *machine, render_container *containe y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { - render_container_add_char(container, x0, y0, chheight, render_get_ui_aspect(), ARGB_WHITE, ui_font, title[x]); - x0 += render_font_get_char_width(ui_font, chheight, render_get_ui_aspect(), title[x]); + container->add_char(x0, y0, chheight, machine->render().ui_aspect(), ARGB_WHITE, *ui_font, title[x]); + x0 += render_font_get_char_width(ui_font, chheight, machine->render().ui_aspect(), title[x]); } /* update the bitmap */ tilemap_update_bitmap(machine, state, mapboxwidth / pixelscale, mapboxheight / pixelscale); /* add the final quad */ - render_container_add_quad(container, mapboxbounds.x0, mapboxbounds.y0, + container->add_quad(mapboxbounds.x0, mapboxbounds.y0, mapboxbounds.x1, mapboxbounds.y1, ARGB_WHITE, state->texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state->tilemap.rotate)); @@ -1058,14 +1052,13 @@ static void tilemap_update_bitmap(running_machine *machine, ui_gfx_state *state, if (state->bitmap == NULL || state->texture == NULL || state->bitmap->format != screen_format || state->bitmap->width != width || state->bitmap->height != height) { /* free the old stuff */ - if (state->texture != NULL) - render_texture_free(state->texture); + machine->render().texture_free(state->texture); global_free(state->bitmap); /* allocate new stuff */ state->bitmap = global_alloc(bitmap_t(width, height, screen_format)); - state->texture = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(state->texture, state->bitmap, NULL, screen_texformat, palette); + state->texture = machine->render().texture_alloc(); + state->texture->set_bitmap(state->bitmap, NULL, screen_texformat, palette); /* force a redraw */ state->bitmap_dirty = TRUE; @@ -1077,7 +1070,7 @@ static void tilemap_update_bitmap(running_machine *machine, ui_gfx_state *state, tilemap_draw_by_index(machine, state->bitmap, state->tilemap.which, state->tilemap.xoffs, state->tilemap.yoffs); /* reset the texture to force an update */ - render_texture_set_bitmap(state->texture, state->bitmap, NULL, screen_texformat, palette); + state->texture->set_bitmap(state->bitmap, NULL, screen_texformat, palette); state->bitmap_dirty = FALSE; } } diff --git a/src/emu/uiimage.c b/src/emu/uiimage.c index ded825ffced..2c2205d5bca 100644 --- a/src/emu/uiimage.c +++ b/src/emu/uiimage.c @@ -147,14 +147,14 @@ static void input_character(char *buffer, size_t buffer_length, unicode_char uni or footer text -------------------------------------------------*/ -static void extra_text_draw_box(float origx1, float origx2, float origy, float yspan, const char *text, int direction) +static void extra_text_draw_box(render_container &ui_container, float origx1, float origx2, float origy, float yspan, const char *text, int direction) { float text_width, text_height; float width, maxwidth; float x1, y1, x2, y2, temp; /* get the size of the text */ - ui_draw_text_full( render_container_get_ui(),text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD, + ui_draw_text_full(&ui_container,text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &text_width, &text_height); width = text_width + (2 * UI_BOX_LR_BORDER); maxwidth = MAX(width, origx2 - origx1); @@ -173,7 +173,7 @@ static void extra_text_draw_box(float origx1, float origx2, float origy, float y } /* draw a box */ - ui_draw_outlined_box(render_container_get_ui(),x1, y1, x2, y2, UI_BACKGROUND_COLOR); + ui_draw_outlined_box(&ui_container,x1, y1, x2, y2, UI_BACKGROUND_COLOR); /* take off the borders */ x1 += UI_BOX_LR_BORDER; @@ -182,7 +182,7 @@ static void extra_text_draw_box(float origx1, float origx2, float origy, float y y2 -= UI_BOX_TB_BORDER; /* draw the text within it */ - ui_draw_text_full(render_container_get_ui(),text, x1, y1, text_width, JUSTIFY_LEFT, WRAP_WORD, + ui_draw_text_full(&ui_container,text, x1, y1, text_width, JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, ARGB_WHITE, ARGB_BLACK, NULL, NULL); } @@ -201,9 +201,9 @@ static void extra_text_render(running_machine *machine, ui_menu *menu, void *sta footer = ((footer != NULL) && (footer[0] != '\0')) ? footer : NULL; if (header != NULL) - extra_text_draw_box(origx1, origx2, origy1, top, header, -1); + extra_text_draw_box(machine->render().ui_container(), origx1, origx2, origy1, top, header, -1); if (footer != NULL) - extra_text_draw_box(origx1, origx2, origy2, bottom, footer, +1); + extra_text_draw_box(machine->render().ui_container(), origx1, origx2, origy2, bottom, footer, +1); } @@ -338,7 +338,7 @@ static void menu_file_create_populate(running_machine *machine, ui_menu *menu, v ui_menu_item_append(menu, "Create", NULL, 0, ITEMREF_CREATE); /* set up custom render proc */ - ui_menu_set_custom_render(menu, file_create_render_extra, ui_get_line_height() + 3.0f * UI_BOX_TB_BORDER, 0); + ui_menu_set_custom_render(menu, file_create_render_extra, ui_get_line_height(*machine) + 3.0f * UI_BOX_TB_BORDER, 0); } @@ -379,7 +379,7 @@ static int create_new_image(device_image_interface *image, const char *directory case ENTTYPE_FILE: /* a file exists here - ask for permission from the user */ - child_menu = ui_menu_alloc(image->device().machine, render_container_get_ui(), menu_confirm_save_as, NULL); + child_menu = ui_menu_alloc(image->device().machine, &image->device().machine->render().ui_container(), menu_confirm_save_as, NULL); child_menustate = (confirm_save_as_menu_state*)ui_menu_alloc_state(child_menu, sizeof(*child_menustate), NULL); child_menustate->yes = yes; ui_menu_stack_push(child_menu); @@ -742,7 +742,7 @@ static file_error menu_file_selector_populate(running_machine *machine, ui_menu ui_menu_set_selection(menu, (void *) selected_entry); /* set up custom render proc */ - ui_menu_set_custom_render(menu, file_selector_render_extra, ui_get_line_height() + 3.0f * UI_BOX_TB_BORDER, 0); + ui_menu_set_custom_render(menu, file_selector_render_extra, ui_get_line_height(*machine) + 3.0f * UI_BOX_TB_BORDER, 0); done: if (directory != NULL) @@ -811,13 +811,13 @@ static void menu_file_selector(running_machine *machine, ui_menu *menu, void *pa case SELECTOR_ENTRY_TYPE_CREATE: /* create */ - child_menu = ui_menu_alloc(machine, render_container_get_ui(), menu_file_create, NULL); + child_menu = ui_menu_alloc(machine, &machine->render().ui_container(), menu_file_create, NULL); child_menustate = (file_create_menu_state*)ui_menu_alloc_state(child_menu, sizeof(*child_menustate), NULL); child_menustate->manager_menustate = menustate->manager_menustate; ui_menu_stack_push(child_menu); break; case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST: - child_menu = ui_menu_alloc(machine, render_container_get_ui(), ui_image_menu_software, menustate->manager_menustate->selected_device); + child_menu = ui_menu_alloc(machine, &machine->render().ui_container(), ui_image_menu_software, menustate->manager_menustate->selected_device); ui_menu_stack_push(child_menu); break; case SELECTOR_ENTRY_TYPE_DRIVE: @@ -919,7 +919,7 @@ static void menu_file_manager_populate(running_machine *machine, ui_menu *menu, } /* set up custom render proc */ - ui_menu_set_custom_render(menu, file_manager_render_extra, 0, ui_get_line_height() + 3.0f * UI_BOX_TB_BORDER); + ui_menu_set_custom_render(menu, file_manager_render_extra, 0, ui_get_line_height(*machine) + 3.0f * UI_BOX_TB_BORDER); } @@ -988,7 +988,7 @@ void ui_image_menu_file_manager(running_machine *machine, ui_menu *menu, void *p ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION); /* push the menu */ - child_menu = ui_menu_alloc(machine, render_container_get_ui(), menu_file_selector, NULL); + child_menu = ui_menu_alloc(machine, &machine->render().ui_container(), menu_file_selector, NULL); child_menustate = (file_selector_menu_state *)ui_menu_alloc_state(child_menu, sizeof(*child_menustate), NULL); child_menustate->manager_menustate = menustate; ui_menu_stack_push(child_menu); diff --git a/src/emu/uimenu.c b/src/emu/uimenu.c index c30a0843654..1b05f1629d9 100644 --- a/src/emu/uimenu.c +++ b/src/emu/uimenu.c @@ -80,9 +80,14 @@ enum enum { VIDEO_ITEM_ROTATE = 0x80000000, + VIDEO_ITEM_BACKDROPS, + VIDEO_ITEM_OVERLAYS, + VIDEO_ITEM_BEZELS, + VIDEO_ITEM_ZOOM, VIDEO_ITEM_VIEW }; + enum { CROSSHAIR_ITEM_VIS = 0, @@ -300,7 +305,7 @@ static void menu_select_game_build_driver_list(ui_menu *menu, select_game_state static void menu_select_game_custom_render(running_machine *machine, ui_menu *menu, void *state, void *selectedref, float top, float bottom, float x, float y, float x2, float y2); /* menu helpers */ -static void menu_render_triangle(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param); +static void menu_render_triangle(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param); static void menu_settings_custom_render_one(render_container *container, float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask); static void menu_settings_custom_render(running_machine *machine, ui_menu *menu, void *state, void *selectedref, float top, float bottom, float x, float y, float x2, float y2); @@ -394,11 +399,11 @@ void ui_menu_init(running_machine *machine) if (x > 256 - 25) alpha = 0xff * (255 - x) / 25; *BITMAP_ADDR32(hilight_bitmap, 0, x) = MAKE_ARGB(alpha,0xff,0xff,0xff); } - hilight_texture = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(hilight_texture, hilight_bitmap, NULL, TEXFORMAT_ARGB32, NULL); + hilight_texture = machine->render().texture_alloc(); + hilight_texture->set_bitmap(hilight_bitmap, NULL, TEXFORMAT_ARGB32); /* create a texture for arrow icons */ - arrow_texture = render_texture_alloc(menu_render_triangle, NULL); + arrow_texture = machine->render().texture_alloc(menu_render_triangle); /* add an exit callback to free memory */ machine->add_notifier(MACHINE_NOTIFY_EXIT, ui_menu_exit); @@ -416,8 +421,8 @@ static void ui_menu_exit(running_machine &machine) ui_menu_clear_free_list(&machine); /* free textures */ - render_texture_free(hilight_texture); - render_texture_free(arrow_texture); + machine.render().texture_free(hilight_texture); + machine.render().texture_free(arrow_texture); } @@ -735,9 +740,9 @@ void ui_menu_set_selection(ui_menu *menu, void *selected_itemref) static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly) { - float line_height = ui_get_line_height(); - float lr_arrow_width = 0.4f * line_height * render_get_ui_aspect(); - float ud_arrow_width = line_height * render_get_ui_aspect(); + float line_height = ui_get_line_height(*machine); + float lr_arrow_width = 0.4f * line_height * machine->render().ui_aspect(); + float ud_arrow_width = line_height * machine->render().ui_aspect(); float gutter_width = lr_arrow_width * 1.3f; float x1, y1, x2, y2; @@ -763,11 +768,11 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly float total_width; /* compute width of left hand side */ - total_width = gutter_width + ui_get_string_width(item->text) + gutter_width; + total_width = gutter_width + ui_get_string_width(*machine, item->text) + gutter_width; /* add in width of right hand side */ if (item->subtext) - total_width += 2.0f * gutter_width + ui_get_string_width(item->subtext); + total_width += 2.0f * gutter_width + ui_get_string_width(*machine, item->subtext); /* track the maximum */ if (total_width > visible_width) @@ -828,7 +833,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly { mouse_target = ui_input_find_mouse(machine, &mouse_target_x, &mouse_target_y, &mouse_button); if (mouse_target != NULL) - if (render_target_map_point_container(mouse_target, mouse_target_x, mouse_target_y, menu->container, &mouse_x, &mouse_y)) + if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *menu->container, mouse_x, mouse_y)) mouse_hit = TRUE; } @@ -874,13 +879,13 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly /* if we have some background hilighting to do, add a quad behind everything else */ if (bgcolor != UI_TEXT_BG_COLOR) - render_container_add_quad(menu->container, line_x0, line_y0, line_x1, line_y1, bgcolor, hilight_texture, + menu->container->add_quad(line_x0, line_y0, line_x1, line_y1, bgcolor, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); /* if we're on the top line, display the up arrow */ if (linenum == 0 && top_line != 0) { - render_container_add_quad( menu->container, + menu->container->add_quad( 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height, 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, @@ -895,7 +900,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly /* if we're on the bottom line, display the down arrow */ else if (linenum == visible_lines - 1 && itemnum != menu->numitems - 1) { - render_container_add_quad( menu->container, + menu->container->add_quad( 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height, 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, @@ -909,7 +914,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly /* if we're just a divider, draw a line */ else if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0) - render_container_add_line(menu->container, visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* if we don't have a subitem, just draw the string centered */ else if (item->subtext == NULL) @@ -931,7 +936,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly item_width += 2.0f * gutter_width; /* if the subitem doesn't fit here, display dots */ - if (ui_get_string_width(subitem_text) > effective_width - item_width) + if (ui_get_string_width(*machine, subitem_text) > effective_width - item_width) { subitem_text = "..."; if (itemnum == menu->selected) @@ -945,7 +950,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly /* apply arrows */ if (itemnum == menu->selected && (item->flags & MENU_FLAG_LEFT_ARROW)) { - render_container_add_quad( menu->container, + menu->container->add_quad( effective_left + effective_width - subitem_width - gutter_width, line_y + 0.1f * line_height, effective_left + effective_width - subitem_width - gutter_width + lr_arrow_width, @@ -956,7 +961,7 @@ static void ui_menu_draw(running_machine *machine, ui_menu *menu, int customonly } if (itemnum == menu->selected && (item->flags & MENU_FLAG_RIGHT_ARROW)) { - render_container_add_quad( menu->container, + menu->container->add_quad( effective_left + effective_width + gutter_width - lr_arrow_width, line_y + 0.1f * line_height, effective_left + effective_width + gutter_width, @@ -1019,8 +1024,8 @@ static void ui_menu_draw_text_box(ui_menu *menu) { const char *text = menu->item[0].text; const char *backtext = menu->item[1].text; - float line_height = ui_get_line_height(); - float lr_arrow_width = 0.4f * line_height * render_get_ui_aspect(); + float line_height = ui_get_line_height(*menu->machine); + float lr_arrow_width = 0.4f * line_height * menu->machine->render().ui_aspect(); float gutter_width = lr_arrow_width; float target_width, target_height, prior_width; float target_x, target_y; @@ -1033,7 +1038,7 @@ static void ui_menu_draw_text_box(ui_menu *menu) target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height; /* maximum against "return to prior menu" text */ - prior_width = ui_get_string_width(backtext) + 2.0f * gutter_width; + prior_width = ui_get_string_width(*menu->machine, backtext) + 2.0f * gutter_width; target_width = MAX(target_width, prior_width); /* determine the target location */ @@ -1059,7 +1064,7 @@ static void ui_menu_draw_text_box(ui_menu *menu) JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, NULL, NULL); /* draw the "return to prior menu" text with a hilight behind it */ - render_container_add_quad(menu->container, + menu->container->add_quad( target_x + 0.5f * UI_LINE_WIDTH, target_y + target_height - line_height, target_x + target_width - 0.5f * UI_LINE_WIDTH, @@ -1557,7 +1562,7 @@ static void menu_main_populate(running_machine *machine, ui_menu *menu, void *st ui_menu_item_append(menu, "Slider Controls", NULL, 0, (void *)menu_sliders); /* add video options menu */ - ui_menu_item_append(menu, "Video Options", NULL, 0, (render_target_get_indexed(1) != NULL) ? (void *)menu_video_targets : (void *)menu_video_options); + ui_menu_item_append(menu, "Video Options", NULL, 0, (machine->render().target_by_index(1) != NULL) ? (void *)menu_video_targets : (void *)menu_video_options); /* add crosshair options menu */ if (crosshair_get_usage(machine)) @@ -2177,8 +2182,8 @@ static void menu_settings_custom_render(running_machine *machine, ui_menu *menu, static void menu_settings_custom_render_one(render_container *container, float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask) { - float switch_field_width = SINGLE_TOGGLE_SWITCH_FIELD_WIDTH * render_get_ui_aspect(); - float switch_width = SINGLE_TOGGLE_SWITCH_WIDTH * render_get_ui_aspect(); + float switch_field_width = SINGLE_TOGGLE_SWITCH_FIELD_WIDTH * container->manager().ui_aspect(); + float switch_width = SINGLE_TOGGLE_SWITCH_WIDTH * container->manager().ui_aspect(); int numtoggles, toggle; float switch_toggle_gap; float y1_off, y1_on; @@ -2194,7 +2199,7 @@ static void menu_settings_custom_render_one(render_container *container, float x dip->name, 0, y1 + (DIP_SWITCH_HEIGHT - UI_TARGET_FONT_HEIGHT) / 2, - x1 - ui_get_string_width(" "), + x1 - ui_get_string_width(container->manager().machine(), " "), JUSTIFY_RIGHT, WRAP_NEVER, DRAW_NORMAL, @@ -2223,13 +2228,13 @@ static void menu_settings_custom_render_one(render_container *container, float x if (dip->mask & (1 << toggle)) { float innery1 = (dip->state & (1 << toggle)) ? y1_on : y1_off; - render_container_add_rect(container, innerx1, innery1, innerx1 + switch_width, innery1 + SINGLE_TOGGLE_SWITCH_HEIGHT, + container->add_rect(innerx1, innery1, innerx1 + switch_width, innery1 + SINGLE_TOGGLE_SWITCH_HEIGHT, (selectedmask & (1 << toggle)) ? UI_DIPSW_COLOR : UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } else { - render_container_add_rect(container, innerx1, y1_off, innerx1 + switch_width, y1_on + SINGLE_TOGGLE_SWITCH_HEIGHT, + container->add_rect(innerx1, y1_off, innerx1 + switch_width, y1_on + SINGLE_TOGGLE_SWITCH_HEIGHT, UI_UNAVAILABLE_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } @@ -2871,7 +2876,7 @@ static void menu_sliders_populate(running_machine *machine, ui_menu *menu, int m break; } - ui_menu_set_custom_render(menu, menu_sliders_custom_render, 0.0f, 2.0f * ui_get_line_height() + 2.0f * UI_BOX_TB_BORDER); + ui_menu_set_custom_render(menu, menu_sliders_custom_render, 0.0f, 2.0f * ui_get_line_height(*machine) + 2.0f * UI_BOX_TB_BORDER); } @@ -2886,7 +2891,7 @@ static void menu_sliders_custom_render(running_machine *machine, ui_menu *menu, if (curslider != NULL) { float bar_left, bar_area_top, bar_width, bar_area_height, bar_top, bar_bottom, default_x, current_x; - float line_height = ui_get_line_height(); + float line_height = ui_get_line_height(*machine); float percentage, default_percentage; astring tempstring; float text_height; @@ -2929,15 +2934,15 @@ static void menu_sliders_custom_render(running_machine *machine, ui_menu *menu, current_x = bar_left + bar_width * percentage; /* fill in the percentage */ - render_container_add_rect(menu->container, bar_left, bar_top, current_x, bar_bottom, UI_SLIDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_rect(bar_left, bar_top, current_x, bar_bottom, UI_SLIDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the top and bottom lines */ - render_container_add_line(menu->container, bar_left, bar_top, bar_left + bar_width, bar_top, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(menu->container, bar_left, bar_bottom, bar_left + bar_width, bar_bottom, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_line(bar_left, bar_top, bar_left + bar_width, bar_top, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_line(bar_left, bar_bottom, bar_left + bar_width, bar_bottom, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw default marker */ - render_container_add_line(menu->container, default_x, bar_area_top, default_x, bar_top, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - render_container_add_line(menu->container, default_x, bar_bottom, default_x, bar_area_top + bar_area_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_line(default_x, bar_area_top, default_x, bar_top, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + menu->container->add_line(default_x, bar_bottom, default_x, bar_area_top + bar_area_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); /* draw the actual text */ ui_draw_text_full(menu->container, tempstring, x1 + UI_BOX_LR_BORDER, y1 + line_height, x2 - x1 - 2.0f * UI_BOX_LR_BORDER, @@ -2978,7 +2983,7 @@ static void menu_video_targets_populate(running_machine *machine, ui_menu *menu) /* find the targets */ for (targetnum = 0; ; targetnum++) { - render_target *target = render_target_get_indexed(targetnum); + render_target *target = machine->render().target_by_index(targetnum); char buffer[40]; /* stop when we run out */ @@ -2999,7 +3004,7 @@ static void menu_video_targets_populate(running_machine *machine, ui_menu *menu) static void menu_video_options(running_machine *machine, ui_menu *menu, void *parameter, void *state) { - render_target *target = (parameter != NULL) ? (render_target *)parameter : render_target_get_indexed(0); + render_target *target = (parameter != NULL) ? (render_target *)parameter : machine->render().first_target(); const ui_menu_event *event; int changed = FALSE; @@ -3018,26 +3023,47 @@ static void menu_video_options(running_machine *machine, ui_menu *menu, void *pa if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT) { int delta = (event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90; - render_target_set_orientation(target, orientation_add(delta, render_target_get_orientation(target))); - if (target == render_get_ui_target()) + target->set_orientation(orientation_add(delta, target->orientation())); + if (target->is_ui_target()) { - render_container_user_settings settings; - render_container_get_user_settings(menu->container, &settings); - settings.orientation = orientation_add(delta ^ ROT180, settings.orientation); - render_container_set_user_settings(menu->container, &settings); + render_container::user_settings settings; + menu->container->get_user_settings(settings); + settings.m_orientation = orientation_add(delta ^ ROT180, settings.m_orientation); + menu->container->set_user_settings(settings); } changed = TRUE; } break; /* layer config bitmasks handle left/right keys the same (toggle) */ - case LAYER_CONFIG_ENABLE_BACKDROP: - case LAYER_CONFIG_ENABLE_OVERLAY: - case LAYER_CONFIG_ENABLE_BEZEL: - case LAYER_CONFIG_ZOOM_TO_SCREEN: + case VIDEO_ITEM_BACKDROPS: if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT) { - render_target_set_layer_config(target, render_target_get_layer_config(target) ^ (FPTR)event->itemref); + target->set_backdrops_enabled(!target->backdrops_enabled()); + changed = TRUE; + } + break; + + case VIDEO_ITEM_OVERLAYS: + if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT) + { + target->set_overlays_enabled(!target->overlays_enabled()); + changed = TRUE; + } + break; + + case VIDEO_ITEM_BEZELS: + if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT) + { + target->set_bezels_enabled(!target->bezels_enabled()); + changed = TRUE; + } + break; + + case VIDEO_ITEM_ZOOM: + if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT) + { + target->set_zoom_to_screen(!target->zoom_to_screen()); changed = TRUE; } break; @@ -3046,7 +3072,7 @@ static void menu_video_options(running_machine *machine, ui_menu *menu, void *pa default: if (event->iptkey == IPT_UI_SELECT && (int)(FPTR)event->itemref >= VIDEO_ITEM_VIEW) { - render_target_set_view(target, (FPTR)event->itemref - VIDEO_ITEM_VIEW); + target->set_view((FPTR)event->itemref - VIDEO_ITEM_VIEW); changed = TRUE; } break; @@ -3066,7 +3092,6 @@ static void menu_video_options(running_machine *machine, ui_menu *menu, void *pa static void menu_video_options_populate(running_machine *machine, ui_menu *menu, render_target *target) { - int layermask = render_target_get_layer_config(target); const char *subtext = ""; astring tempstring; int viewnum; @@ -3075,7 +3100,7 @@ static void menu_video_options_populate(running_machine *machine, ui_menu *menu, /* add items for each view */ for (viewnum = 0; ; viewnum++) { - const char *name = render_target_get_view_name(target, viewnum); + const char *name = target->view_name(viewnum); if (name == NULL) break; @@ -3088,7 +3113,7 @@ static void menu_video_options_populate(running_machine *machine, ui_menu *menu, ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL); /* add a rotate item */ - switch (render_target_get_orientation(target)) + switch (target->orientation()) { case ROT0: subtext = "None"; break; case ROT90: subtext = "CW 90" UTF8_DEGREES; break; @@ -3098,20 +3123,20 @@ static void menu_video_options_populate(running_machine *machine, ui_menu *menu, ui_menu_item_append(menu, "Rotate", subtext, MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_ROTATE); /* backdrop item */ - enabled = layermask & LAYER_CONFIG_ENABLE_BACKDROP; - ui_menu_item_append(menu, "Backdrops", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)LAYER_CONFIG_ENABLE_BACKDROP); + enabled = target->backdrops_enabled(); + ui_menu_item_append(menu, "Backdrops", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_BACKDROPS); /* overlay item */ - enabled = layermask & LAYER_CONFIG_ENABLE_OVERLAY; - ui_menu_item_append(menu, "Overlays", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)LAYER_CONFIG_ENABLE_OVERLAY); + enabled = target->overlays_enabled(); + ui_menu_item_append(menu, "Overlays", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_OVERLAYS); /* bezel item */ - enabled = layermask & LAYER_CONFIG_ENABLE_BEZEL; - ui_menu_item_append(menu, "Bezels", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)LAYER_CONFIG_ENABLE_BEZEL); + enabled = target->bezels_enabled(); + ui_menu_item_append(menu, "Bezels", enabled ? "Enabled" : "Disabled", enabled ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_BEZELS); /* cropping */ - enabled = layermask & LAYER_CONFIG_ZOOM_TO_SCREEN; - ui_menu_item_append(menu, "View", enabled ? "Cropped" : "Full", enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)LAYER_CONFIG_ZOOM_TO_SCREEN); + enabled = target->zoom_to_screen(); + ui_menu_item_append(menu, "View", enabled ? "Cropped" : "Full", enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)VIDEO_ITEM_ZOOM); } @@ -3556,7 +3581,7 @@ static void menu_select_game_populate(running_machine *machine, ui_menu *menu, s } /* configure the custom rendering */ - ui_menu_set_custom_render(menu, menu_select_game_custom_render, ui_get_line_height() + 3.0f * UI_BOX_TB_BORDER, 4.0f * ui_get_line_height() + 3.0f * UI_BOX_TB_BORDER); + ui_menu_set_custom_render(menu, menu_select_game_custom_render, ui_get_line_height(*machine) + 3.0f * UI_BOX_TB_BORDER, 4.0f * ui_get_line_height(*machine) + 3.0f * UI_BOX_TB_BORDER); } @@ -3787,7 +3812,7 @@ static void menu_select_game_custom_render(running_machine *machine, ui_menu *me { ui_draw_text_full(menu->container, &tempbuf[line][0], x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, NULL, NULL); - y1 += ui_get_line_height(); + y1 += ui_get_line_height(*machine); } } @@ -3803,23 +3828,23 @@ static void menu_select_game_custom_render(running_machine *machine, ui_menu *me indicators -------------------------------------------------*/ -static void menu_render_triangle(bitmap_t *dest, const bitmap_t *source, const rectangle *sbounds, void *param) +static void menu_render_triangle(bitmap_t &dest, const bitmap_t &source, const rectangle &sbounds, void *param) { - int halfwidth = dest->width / 2; - int height = dest->height; + int halfwidth = dest.width / 2; + int height = dest.height; int x, y; /* start with all-transparent */ - bitmap_fill(dest, NULL, MAKE_ARGB(0x00,0x00,0x00,0x00)); + bitmap_fill(&dest, NULL, MAKE_ARGB(0x00,0x00,0x00,0x00)); /* render from the tip to the bottom */ for (y = 0; y < height; y++) { int linewidth = (y * (halfwidth - 1) + (height / 2)) * 255 * 2 / height; - UINT32 *target = BITMAP_ADDR32(dest, y, halfwidth); + UINT32 *target = BITMAP_ADDR32(&dest, y, halfwidth); /* don't antialias if height < 12 */ - if (dest->height < 12) + if (dest.height < 12) { int pixels = (linewidth + 254) / 255; if (pixels % 2 == 0) pixels++; diff --git a/src/emu/video.c b/src/emu/video.c index 8e2ad00044b..0c1e2c7fe65 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -193,7 +193,7 @@ static void video_mng_record_frame(running_machine *machine); static void video_avi_record_frame(running_machine *machine); /* software rendering */ -static void rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); @@ -311,18 +311,16 @@ void video_init(running_machine *machine) /* the native target is hard-coded to our internal layout and has all options disabled */ if (global.snap_native) { - global.snap_target = render_target_alloc(machine, layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); - assert(global.snap_target != NULL); - render_target_set_layer_config(global.snap_target, 0); + global.snap_target = machine->render().target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); + global.snap_target->set_layer_config(0); } /* other targets select the specified view and turn off effects */ else { - global.snap_target = render_target_alloc(machine, NULL, RENDER_CREATE_HIDDEN); - assert(global.snap_target != NULL); - render_target_set_view(global.snap_target, video_get_view_for_target(machine, global.snap_target, viewname, 0, 1)); - render_target_set_layer_config(global.snap_target, render_target_get_layer_config(global.snap_target) & ~LAYER_CONFIG_ENABLE_SCREEN_OVERLAY); + global.snap_target = machine->render().target_alloc(NULL, RENDER_CREATE_HIDDEN); + global.snap_target->set_view(video_get_view_for_target(machine, global.snap_target, viewname, 0, 1)); + global.snap_target->set_screen_overlay_enabled(false); } /* extract snap resolution if present */ @@ -364,8 +362,7 @@ static void video_exit(running_machine &machine) gfx_element_free(machine.gfx[i]); /* free the snapshot target */ - if (global.snap_target != NULL) - render_target_free(global.snap_target); + machine.render().target_free(global.snap_target); if (global.snap_bitmap != NULL) global_free(global.snap_bitmap); @@ -455,7 +452,7 @@ void video_frame_update(running_machine *machine, int debug) } /* draw the user interface */ - ui_update_and_render(machine, render_container_get_ui()); + ui_update_and_render(machine, &machine->render().ui_container()); /* update the internal render debugger */ debugint_update_during_game(machine); @@ -991,7 +988,7 @@ static void update_refresh_speed(running_machine *machine) /* only do this if the refreshspeed option is used */ if (options_get_bool(machine->options(), OPTION_REFRESHSPEED)) { - float minrefresh = render_get_max_update_rate(); + float minrefresh = machine->render().max_update_rate(); if (minrefresh != 0) { attoseconds_t min_frame_period = ATTOSECONDS_PER_SECOND; @@ -1156,7 +1153,7 @@ void video_save_active_screen_snapshots(running_machine *machine) { /* write one snapshot per visible screen */ for (screen_device *screen = screen_first(*machine); screen != NULL; screen = screen_next(screen)) - if (render_is_live_screen(screen)) + if (machine->render().is_live(*screen)) { file_error filerr = mame_fopen_next(machine, SEARCHPATH_SCREENSHOT, "png", &fp); if (filerr == FILERR_NONE) @@ -1188,7 +1185,6 @@ void video_save_active_screen_snapshots(running_machine *machine) static void create_snapshot_bitmap(device_t *screen) { - const render_primitive_list *primlist; INT32 width, height; int view_index; @@ -1197,15 +1193,15 @@ static void create_snapshot_bitmap(device_t *screen) { view_index = screen->machine->m_devicelist.index(SCREEN, screen->tag()); assert(view_index != -1); - render_target_set_view(global.snap_target, view_index); + global.snap_target->set_view(view_index); } /* get the minimum width/height and set it on the target */ width = global.snap_width; height = global.snap_height; if (width == 0 || height == 0) - render_target_get_minimum_size(global.snap_target, &width, &height); - render_target_set_bounds(global.snap_target, width, height, 0); + global.snap_target->compute_minimum_size(width, height); + global.snap_target->set_bounds(width, height); /* if we don't have a bitmap, or if it's not the right size, allocate a new one */ if (global.snap_bitmap == NULL || width != global.snap_bitmap->width || height != global.snap_bitmap->height) @@ -1217,10 +1213,10 @@ static void create_snapshot_bitmap(device_t *screen) } /* render the screen there */ - primlist = render_target_get_primitives(global.snap_target); - osd_lock_acquire(primlist->lock); - rgb888_draw_primitives(primlist->head, global.snap_bitmap->base, width, height, global.snap_bitmap->rowpixels); - osd_lock_release(primlist->lock); + render_primitive_list &primlist = global.snap_target->get_primitives(); + primlist.acquire_lock(); + rgb888_draw_primitives(primlist, global.snap_bitmap->base, width, height, global.snap_bitmap->rowpixels); + primlist.release_lock(); } @@ -1586,7 +1582,7 @@ int video_get_view_for_target(running_machine *machine, render_target *target, c /* scan for a matching view name */ for (viewindex = 0; ; viewindex++) { - const char *name = render_target_get_view_name(target, viewindex); + const char *name = target->view_name(viewindex); /* stop scanning when we hit NULL */ if (name == NULL) @@ -1610,7 +1606,7 @@ int video_get_view_for_target(running_machine *machine, render_target *target, c /* find the first view with this screen and this screen only */ for (viewindex = 0; ; viewindex++) { - UINT32 viewscreens = render_target_get_view_screens(target, viewindex); + UINT32 viewscreens = target->view_screens(viewindex); if (viewscreens == (1 << targetindex)) break; if (viewscreens == 0) @@ -1626,7 +1622,7 @@ int video_get_view_for_target(running_machine *machine, render_target *target, c { for (viewindex = 0; ; viewindex++) { - UINT32 viewscreens = render_target_get_view_screens(target, viewindex); + UINT32 viewscreens = target->view_screens(viewindex); if (viewscreens == (1 << scrcount) - 1) break; if (viewscreens == 0) @@ -1636,7 +1632,7 @@ int video_get_view_for_target(running_machine *machine, render_target *target, c } /* make sure it's a valid view */ - if (render_target_get_view_name(target, viewindex) == NULL) + if (target->view_name(viewindex) == NULL) viewindex = 0; return viewindex; @@ -1897,6 +1893,7 @@ bool screen_device_config::device_validity_check(const game_driver &driver) cons screen_device::screen_device(running_machine &_machine, const screen_device_config &config) : device_t(_machine, config), m_config(config), + m_container(NULL), m_width(m_config.m_width), m_height(m_config.m_height), m_visarea(m_config.m_visarea), @@ -1930,10 +1927,8 @@ screen_device::screen_device(running_machine &_machine, const screen_device_conf screen_device::~screen_device() { - if (m_texture[0] != NULL) - render_texture_free(m_texture[0]); - if (m_texture[1] != NULL) - render_texture_free(m_texture[1]); + m_machine.render().texture_free(m_texture[0]); + m_machine.render().texture_free(m_texture[1]); if (m_burnin != NULL) finalize_burnin(); } @@ -1946,17 +1941,16 @@ screen_device::~screen_device() void screen_device::device_start() { // get and validate that the container for this screen exists - render_container *container = render_container_get_screen(this); - assert(container != NULL); + m_container = m_machine.render().container_for_screen(this); // configure the default cliparea - render_container_user_settings settings; - render_container_get_user_settings(container, &settings); - settings.xoffset = m_config.m_xoffset; - settings.yoffset = m_config.m_yoffset; - settings.xscale = m_config.m_xscale; - settings.yscale = m_config.m_yscale; - render_container_set_user_settings(container, &settings); + render_container::user_settings settings; + m_container->get_user_settings(settings); + settings.m_xoffset = m_config.m_xoffset; + settings.m_yoffset = m_config.m_yoffset; + settings.m_xscale = m_config.m_xscale; + settings.m_yscale = m_config.m_yscale; + m_container->set_user_settings(settings); // allocate the VBLANK timers m_vblank_begin_timer = timer_alloc(machine, static_vblank_begin_callback, (void *)this); @@ -2096,10 +2090,8 @@ void screen_device::realloc_screen_bitmaps() if (m_width > curwidth || m_height > curheight) { // free what we have currently - if (m_texture[0] != NULL) - render_texture_free(m_texture[0]); - if (m_texture[1] != NULL) - render_texture_free(m_texture[1]); + global_free(m_texture[0]); + global_free(m_texture[1]); if (m_bitmap[0] != NULL) auto_free(machine, m_bitmap[0]); if (m_bitmap[1] != NULL) @@ -2126,10 +2118,10 @@ void screen_device::realloc_screen_bitmaps() bitmap_set_palette(m_bitmap[1], machine->palette); // allocate textures - m_texture[0] = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(m_texture[0], m_bitmap[0], &m_visarea, m_texture_format, palette); - m_texture[1] = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(m_texture[1], m_bitmap[1], &m_visarea, m_texture_format, palette); + m_texture[0] = m_machine.render().texture_alloc(); + m_texture[0]->set_bitmap(m_bitmap[0], &m_visarea, m_texture_format, palette); + m_texture[1] = m_machine.render().texture_alloc(); + m_texture[1]->set_bitmap(m_bitmap[1], &m_visarea, m_texture_format, palette); } } @@ -2180,7 +2172,7 @@ bool screen_device::update_partial(int scanline) } // skip if this screen is not visible anywhere - if (!render_is_live_screen(this)) + if (!m_machine.render().is_live(*this)) { LOG_PARTIAL_UPDATES(("skipped because screen not live\n")); return FALSE; @@ -2460,7 +2452,7 @@ void screen_device::scanline_update_callback(int scanline) bool screen_device::update_quads() { // only update if live - if (render_is_live_screen(this)) + if (m_machine.render().is_live(*this)) { // only update if empty and not a vector game; otherwise assume the driver did it directly if (m_config.m_type != SCREEN_TYPE_VECTOR && (machine->config->m_video_attributes & VIDEO_SELF_RENDER) == 0) @@ -2473,15 +2465,15 @@ bool screen_device::update_quads() fixedvis.max_y++; palette_t *palette = (m_texture_format == TEXFORMAT_PALETTE16) ? machine->palette : NULL; - render_texture_set_bitmap(m_texture[m_curbitmap], m_bitmap[m_curbitmap], &fixedvis, m_texture_format, palette); + m_texture[m_curbitmap]->set_bitmap(m_bitmap[m_curbitmap], &fixedvis, m_texture_format, palette); m_curtexture = m_curbitmap; m_curbitmap = 1 - m_curbitmap; } // create an empty container with a single quad - render_container_empty(render_container_get_screen(this)); - render_screen_add_quad(this, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), m_texture[m_curtexture], PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); + m_container->empty(); + m_container->add_quad(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), m_texture[m_curtexture], PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); } } diff --git a/src/emu/video.h b/src/emu/video.h index da2134947a8..7f6cc17c783 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -72,7 +72,7 @@ enum screen_type_enum // forward references class render_target; -struct render_texture; +class render_texture; class screen_device; @@ -155,6 +155,7 @@ public: int height() const { return m_height; } const rectangle &visible_area() const { return m_visarea; } bitmap_format format() const { return m_config.m_format; } + render_container &container() const { assert(m_container != NULL); return *m_container; } // dynamic configuration void configure(int width, int height, const rectangle &visarea, attoseconds_t frame_period); @@ -218,6 +219,7 @@ private: // internal state const screen_device_config &m_config; + render_container * m_container; // pointer to our container // dimensions int m_width; // current width (HTOTAL) diff --git a/src/emu/video/vector.c b/src/emu/video/vector.c index b1e6be46e69..f636cb00717 100644 --- a/src/emu/video/vector.c +++ b/src/emu/video/vector.c @@ -269,8 +269,8 @@ VIDEO_UPDATE( vector ) curpoint = vector_list; - render_container_empty(render_container_get_screen(screen)); - render_screen_add_rect(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + screen->container().empty(); + screen->container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); clip.x0 = clip.y0 = 0.0f; clip.x1 = clip.y1 = 1.0f; @@ -300,7 +300,7 @@ VIDEO_UPDATE( vector ) if (curpoint->intensity != 0) if (!render_clip_line(&coords, &clip)) - render_screen_add_line(screen, coords.x0, coords.y0, coords.x1, coords.y1, + screen->container().add_line(coords.x0, coords.y0, coords.x1, coords.y1, beam_width * (1.0f / (float)VECTOR_WIDTH_DENOM), (curpoint->intensity << 24) | (curpoint->col & 0xffffff), flags); diff --git a/src/mame/drivers/mazerbla.c b/src/mame/drivers/mazerbla.c index 223e4d31c95..f989206b6f4 100644 --- a/src/mame/drivers/mazerbla.c +++ b/src/mame/drivers/mazerbla.c @@ -215,7 +215,7 @@ VIDEO_UPDATE( test_vcu ) if (dbg_info) { sprintf(buf,"I-info, G-gfx, C-color, V-vbank, 1-4 enable planes"); - ui_draw_text(buf, 10, 0 * ui_get_line_height()); + ui_draw_text(buf, 10, 0 * ui_get_line_height(*screen->machine)); sprintf(buf,"g:%1i c:%1i v:%1i vbk=%1i planes=%1i%1i%1i%1i ", dbg_gfx_e&1, dbg_clr_e&1, dbg_vbank, vbank&1, planes_enabled[0], @@ -223,7 +223,7 @@ VIDEO_UPDATE( test_vcu ) planes_enabled[2], planes_enabled[3] ); - ui_draw_text(buf, 10, 1 * ui_get_line_height()); + ui_draw_text(buf, 10, 1 * ui_get_line_height(*screen->machine)); if (dbg_lookup!=4) { @@ -238,7 +238,7 @@ VIDEO_UPDATE( test_vcu ) { sprintf(buf + strlen(buf), "%02x ", lookup_ram[lookup_offs + x + y * 16]); } - ui_draw_text(buf, 0, (2 + y) * ui_get_line_height()); + ui_draw_text(buf, 0, (2 + y) * ui_get_line_height(*screen->machine)); } } } diff --git a/src/mame/machine/fddebug.c b/src/mame/machine/fddebug.c index c6d6473cdc0..fb747707a6a 100644 --- a/src/mame/machine/fddebug.c +++ b/src/mame/machine/fddebug.c @@ -676,8 +676,8 @@ void fd1094_regenerate_key(running_machine *machine) (*key_changed)(machine); /* force all memory and disassembly views to update */ - machine->m_debug_view->update_all(DVT_MEMORY); - machine->m_debug_view->update_all(DVT_DISASSEMBLY); + machine->debug_view().update_all(DVT_MEMORY); + machine->debug_view().update_all(DVT_DISASSEMBLY); /* reset keydirty */ keydirty = FALSE; @@ -1014,8 +1014,8 @@ static void execute_fdstate(running_machine *machine, int ref, int params, const return; fd1094_set_state(keyregion, newstate); fd1094_regenerate_key(machine); - machine->m_debug_view->update_all(DVT_MEMORY); - machine->m_debug_view->update_all(DVT_DISASSEMBLY); + machine->debug_view().update_all(DVT_MEMORY); + machine->debug_view().update_all(DVT_DISASSEMBLY); } /* 0 parameters displays the current state */ diff --git a/src/mame/video/deco16ic.c b/src/mame/video/deco16ic.c index 664e526a821..d47b9173a9c 100644 --- a/src/mame/video/deco16ic.c +++ b/src/mame/video/deco16ic.c @@ -1077,7 +1077,7 @@ void deco16ic_print_debug_info(running_device *device, bitmap_t *bitmap) sprintf(&buf[strlen(buf)],"%04X", deco16ic->priority); - ui_draw_text(render_container_get_ui(), buf, 60, 40); + ui_draw_text(&device->machine->render().ui_container(), buf, 60, 40); } /*****************************************************************************************/ diff --git a/src/mame/video/ssv.c b/src/mame/video/ssv.c index f1b20ff5118..59132b99203 100644 --- a/src/mame/video/ssv.c +++ b/src/mame/video/ssv.c @@ -948,7 +948,7 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta if (input_code_pressed(machine, KEYCODE_Z)) /* Display some info on each sprite */ { char buf[30]; sprintf(buf, "%02X",/*(s2[2] & ~0x3ff)>>8*/mode>>8); - ui_draw_text(render_container_get_ui(), buf, sx, sy); + ui_draw_text(&machine->render().ui_container(), buf, sx, sy); } #endif @@ -1129,7 +1129,7 @@ static void gdfs_draw_zooming_sprites(running_machine *machine, bitmap_t *bitmap { char buf[10]; sprintf(buf, "%X",size); - ui_draw_text(render_container_get_ui(), buf, sx / 0x10000, sy / 0x10000); + ui_draw_text(&machine->render().ui_container(), buf, sx / 0x10000, sy / 0x10000); } #endif } /* single-sprites */ diff --git a/src/mame/video/taito_f3.c b/src/mame/video/taito_f3.c index bfc14a1f8aa..fe8835cad7d 100644 --- a/src/mame/video/taito_f3.c +++ b/src/mame/video/taito_f3.c @@ -411,7 +411,7 @@ static int (**dpix_sp[9])(UINT32 s_pix); /******************************************************************************/ -static void print_debug_info(bitmap_t *bitmap) +static void print_debug_info(running_machine *machine, bitmap_t *bitmap) { int l[16]; char buf[64*16]; @@ -480,7 +480,7 @@ static void print_debug_info(bitmap_t *bitmap) l[3]=f3_line_ram[0x15e0]&0xffff; bufptr += sprintf(bufptr,"5000: %04x %04x %04x %04x\n",l[0],l[1],l[2],l[3]); - ui_draw_text(render_container_get_ui(), buf, 60, 40); + ui_draw_text(&machine->render().ui_container(), buf, 60, 40); } /******************************************************************************/ @@ -3292,6 +3292,6 @@ VIDEO_UPDATE( f3 ) scanline_draw(screen->machine, bitmap,cliprect); if (VERBOSE) - print_debug_info(bitmap); + print_debug_info(screen->machine, bitmap); return 0; } diff --git a/src/mame/video/tx1.c b/src/mame/video/tx1.c index 5e9506aa27c..514f922e2e2 100644 --- a/src/mame/video/tx1.c +++ b/src/mame/video/tx1.c @@ -124,7 +124,6 @@ static UINT8 *tx1_obj_bmp; static UINT8 *tx1_rod_bmp; static bitmap_t *tx1_bitmap; -static render_texture *tx1_texture; /*************************************************************************** @@ -1122,7 +1121,6 @@ VIDEO_START( tx1 ) { /* Allocate a large bitmap that covers the three screens */ tx1_bitmap = auto_bitmap_alloc(machine, 768, 256, BITMAP_FORMAT_INDEXED16); - tx1_texture = render_texture_alloc(NULL, NULL); /* Allocate some bitmaps */ tx1_chr_bmp = auto_alloc_array(machine, UINT8, 256 * 3 * 240); diff --git a/src/osd/osdmini/minimain.c b/src/osd/osdmini/minimain.c index d039b50138a..1c8d49c0884 100644 --- a/src/osd/osdmini/minimain.c +++ b/src/osd/osdmini/minimain.c @@ -105,9 +105,7 @@ int main(int argc, char *argv[]) void osd_init(running_machine *machine) { // initialize the video system by allocating a rendering target - our_target = render_target_alloc(machine, NULL, 0); - if (our_target == NULL) - fatalerror("Error creating render target"); + our_target = machine->render().target_alloc(); // nothing yet to do to initialize sound, since we don't have any // sound updates are handled by osd_update_audio_stream() below @@ -164,13 +162,13 @@ void osd_update(running_machine *machine, int skip_redraw) int minwidth, minheight; // get the minimum width/height for the current layout - render_target_get_minimum_size(our_target, &minwidth, &minheight); + our_target->compute_minimum_size(minwidth, minheight); // make that the size of our target - render_target_set_bounds(our_target, minwidth, minheight, 0); + our_target->render_target_set_bounds(minwidth, minheight); // get the list of primitives for the target at the current size - primlist = render_target_get_primitives(our_target); + primlist = our_target->get_primitives(); // lock them, and then render them osd_lock_acquire(primlist->lock); diff --git a/src/osd/sdl/draw13.c b/src/osd/sdl/draw13.c index 1ff36621792..6e424578814 100644 --- a/src/osd/sdl/draw13.c +++ b/src/osd/sdl/draw13.c @@ -686,8 +686,8 @@ static const render_primitive_list *draw13_window_get_primitives(sdl_window_info { sdlwindow_blit_surface_size(window, window->monitor->center_width, window->monitor->center_height); } - render_target_set_bounds(window->target, window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); - return render_target_get_primitives(window->target); + window->target->set_bounds(window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); + return window->target->get_primitives(); } //============================================================ @@ -758,7 +758,7 @@ static int draw13_window_draw(sdl_window_info *window, UINT32 dc, int update) switch (prim->type) { - case RENDER_PRIMITIVE_LINE: + case render_primitive::LINE: sr = (int)(255.0f * prim->color.r); sg = (int)(255.0f * prim->color.g); sb = (int)(255.0f * prim->color.b); @@ -769,7 +769,7 @@ static int draw13_window_draw(sdl_window_info *window, UINT32 dc, int update) SDL_RenderDrawLine(prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, prim->bounds.x1 + hofs, prim->bounds.y1 + vofs); break; - case RENDER_PRIMITIVE_QUAD: + case render_primitive::QUAD: texture = texture_update(window, prim); if (texture) blit_pixels += (texture->rawheight * texture->rawwidth); diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c index b4a90cedb67..bacdee32324 100644 --- a/src/osd/sdl/drawogl.c +++ b/src/osd/sdl/drawogl.c @@ -349,7 +349,7 @@ static int drawogl_window_create(sdl_window_info *window, int width, int height) static void drawogl_window_resize(sdl_window_info *window, int width, int height); static void drawogl_window_destroy(sdl_window_info *window); static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update); -static const render_primitive_list *drawogl_window_get_primitives(sdl_window_info *window); +static render_primitive_list &drawogl_window_get_primitives(sdl_window_info *window); static void drawogl_destroy_all_textures(sdl_window_info *window); static void drawogl_window_clear(sdl_window_info *window); static int drawogl_xy_to_render_target(sdl_window_info *window, int x, int y, int *xt, int *yt); @@ -837,7 +837,7 @@ static int drawogl_xy_to_render_target(sdl_window_info *window, int x, int y, in // drawogl_window_get_primitives //============================================================ -static const render_primitive_list *drawogl_window_get_primitives(sdl_window_info *window) +static render_primitive_list &drawogl_window_get_primitives(sdl_window_info *window) { if ((!window->fullscreen) || (video_config.switchres)) { @@ -847,8 +847,8 @@ static const render_primitive_list *drawogl_window_get_primitives(sdl_window_inf { sdlwindow_blit_surface_size(window, window->monitor->center_width, window->monitor->center_height); } - render_target_set_bounds(window->target, window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); - return render_target_get_primitives(window->target); + window->target->set_bounds(window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); + return window->target->get_primitives(); } //============================================================ @@ -1324,10 +1324,10 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) sdl->last_hofs = hofs; sdl->last_vofs = vofs; - osd_lock_acquire(window->primlist->lock); + window->primlist->acquire_lock(); // now draw - for (prim = window->primlist->head; prim != NULL; prim = prim->next) + for (prim = window->primlist->first(); prim != NULL; prim = prim->next()) { int i; @@ -1337,7 +1337,7 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) * Try to stay in one Begin/End block as long as possible, * since entering and leaving one is most expensive.. */ - case RENDER_PRIMITIVE_LINE: + case render_primitive::LINE: #if !USE_WIN32_STYLE_LINES // check if it's really a point if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0)) @@ -1465,7 +1465,7 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) #endif break; - case RENDER_PRIMITIVE_QUAD: + case render_primitive::QUAD: if(pendingPrimitive!=GL_NO_PRIMITIVE) { @@ -1531,6 +1531,9 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) texture=NULL; } break; + + default: + throw emu_fatalerror("Unexpected render_primitive type"); } } @@ -1540,7 +1543,7 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) pendingPrimitive=GL_NO_PRIMITIVE; } - osd_lock_release(window->primlist->lock); + window->primlist->release_lock(); sdl->init_context = 0; #if (!SDL_VERSION_ATLEAST(1,3,0)) @@ -2945,7 +2948,7 @@ static void texture_shader_update(sdl_window_info *window, texture_info *texture { if (scrnum == window->start_viewscreen) { - container = render_container_get_screen(screen); + container = &screen->container(); } scrnum++; @@ -2953,8 +2956,8 @@ static void texture_shader_update(sdl_window_info *window, texture_info *texture if (container!=NULL) { - render_container_user_settings settings; - render_container_get_user_settings(container, &settings); + render_container::user_settings settings; + container->get_user_settings(settings); //FIXME: Intended behaviour #if 1 vid_attributes[0] = options_get_float(window->machine->options(), OPTION_GAMMA); @@ -3128,10 +3131,10 @@ static void drawogl_destroy_all_textures(sdl_window_info *window) SDL_GL_MakeCurrent(window->sdl_window, sdl->gl_context_id); #endif - if(window->primlist && window->primlist->lock) + if(window->primlist) { lock=TRUE; - osd_lock_acquire(window->primlist->lock); + window->primlist->acquire_lock(); } glFinish(); @@ -3210,7 +3213,7 @@ static void drawogl_destroy_all_textures(sdl_window_info *window) sdl->initialized = 0; if (lock) - osd_lock_release(window->primlist->lock); + window->primlist->release_lock(); } //============================================================ diff --git a/src/osd/sdl/drawsdl.c b/src/osd/sdl/drawsdl.c index 35aa11647ee..79a28d809f5 100644 --- a/src/osd/sdl/drawsdl.c +++ b/src/osd/sdl/drawsdl.c @@ -102,7 +102,7 @@ static void drawsdl_attach(sdl_draw_info *info, sdl_window_info *window); static int drawsdl_window_create(sdl_window_info *window, int width, int height); static void drawsdl_window_resize(sdl_window_info *window, int width, int height); static void drawsdl_window_destroy(sdl_window_info *window); -static const render_primitive_list *drawsdl_window_get_primitives(sdl_window_info *window); +static render_primitive_list &drawsdl_window_get_primitives(sdl_window_info *window); static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update); static void drawsdl_destroy_all_textures(sdl_window_info *window); static void drawsdl_window_clear(sdl_window_info *window); @@ -113,11 +113,11 @@ static void setup_texture(sdl_window_info *window, int tempwidth, int tempheight #endif // soft rendering -static void drawsdl_rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_bgr888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_bgra888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_rgb565_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_rgb555_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawsdl_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawsdl_bgr888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawsdl_bgra888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawsdl_rgb565_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawsdl_rgb555_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); // YUV overlays @@ -265,7 +265,7 @@ static void setup_texture(sdl_window_info *window, int tempwidth, int tempheight if (sdl_sm->is_scale) { - render_target_get_minimum_size(window->target, &sdl->hw_scale_width, &sdl->hw_scale_height); + window->target->compute_minimum_size(sdl->hw_scale_width, sdl->hw_scale_height); if (video_config.prescale) { sdl->hw_scale_width *= video_config.prescale; @@ -308,7 +308,7 @@ static void yuv_overlay_init(sdl_window_info *window) const sdl_scale_mode *sdl_sm = sdl->scale_mode; int minimum_width, minimum_height; - render_target_get_minimum_size(window->target, &minimum_width, &minimum_height); + window->target->compute_minimum_size(minimum_width, minimum_height); if (video_config.prescale) { @@ -615,7 +615,7 @@ static int drawsdl_xy_to_render_target(sdl_window_info *window, int x, int y, in // drawsdl_window_get_primitives //============================================================ -static const render_primitive_list *drawsdl_window_get_primitives(sdl_window_info *window) +static render_primitive_list &drawsdl_window_get_primitives(sdl_window_info *window) { sdl_info *sdl = (sdl_info *) window->dxdata; @@ -628,10 +628,10 @@ static const render_primitive_list *drawsdl_window_get_primitives(sdl_window_inf sdlwindow_blit_surface_size(window, window->monitor->center_width, window->monitor->center_height); } if (!sdl->scale_mode->is_scale) - render_target_set_bounds(window->target, window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); + window->target->set_bounds(window->blitwidth, window->blitheight, sdlvideo_monitor_get_aspect(window->monitor)); else - render_target_set_bounds(window->target, sdl->hw_scale_width, sdl->hw_scale_height, 0); - return render_target_get_primitives(window->target); + window->target->set_bounds(sdl->hw_scale_width, sdl->hw_scale_height); + return window->target->get_primitives(); } //============================================================ @@ -768,7 +768,7 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) sdl->last_hofs = hofs; sdl->last_vofs = vofs; - osd_lock_acquire(window->primlist->lock); + window->primlist->acquire_lock(); // render to it if (!sdl->scale_mode->is_yuv) @@ -791,23 +791,23 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) switch (rmask) { case 0x0000ff00: - drawsdl_bgra888_draw_primitives(window->primlist->head, surfptr, mamewidth, mameheight, pitch / 4); + drawsdl_bgra888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x00ff0000: - drawsdl_rgb888_draw_primitives(window->primlist->head, surfptr, mamewidth, mameheight, pitch / 4); + drawsdl_rgb888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x000000ff: - drawsdl_bgr888_draw_primitives(window->primlist->head, surfptr, mamewidth, mameheight, pitch / 4); + drawsdl_bgr888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0xf800: - drawsdl_rgb565_draw_primitives(window->primlist->head, surfptr, mamewidth, mameheight, pitch / 2); + drawsdl_rgb565_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); break; case 0x7c00: - drawsdl_rgb555_draw_primitives(window->primlist->head, surfptr, mamewidth, mameheight, pitch / 2); + drawsdl_rgb555_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); break; default: @@ -819,11 +819,11 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) { assert (sdl->yuv_bitmap != NULL); assert (surfptr != NULL); - drawsdl_rgb555_draw_primitives(window->primlist->head, sdl->yuv_bitmap, sdl->hw_scale_width, sdl->hw_scale_height, sdl->hw_scale_width); + drawsdl_rgb555_draw_primitives(*window->primlist, sdl->yuv_bitmap, sdl->hw_scale_width, sdl->hw_scale_height, sdl->hw_scale_width); sdl->scale_mode->yuv_blit((UINT16 *)sdl->yuv_bitmap, sdl, surfptr, pitch); } - osd_lock_release(window->primlist->lock); + window->primlist->release_lock(); // unlock and flip #if (!SDL_VERSION_ATLEAST(1,3,0)) diff --git a/src/osd/sdl/dview.c b/src/osd/sdl/dview.c index 9e47ba60e8c..a1dbe008ccc 100644 --- a/src/osd/sdl/dview.c +++ b/src/osd/sdl/dview.c @@ -423,6 +423,6 @@ GtkWidget *dview_new(const gchar *widget_name, const gchar *string1, const gchar void dview_set_debug_view(DView *dv, running_machine *machine, debug_view_type type) { - dv->view = machine->m_debug_view->alloc_view(type, dview_update, dv); + dv->view = machine->debug_view().alloc_view(type, dview_update, dv); dv->dv_type = type; } diff --git a/src/osd/sdl/video.c b/src/osd/sdl/video.c index deb60f0a51b..d34d41fcddc 100644 --- a/src/osd/sdl/video.c +++ b/src/osd/sdl/video.c @@ -838,7 +838,7 @@ static void load_effect_overlay(running_machine *machine, const char *filename) // set the overlay on all screens for (screen_device *screen = screen_first(*machine); screen != NULL; screen = screen_next(screen)) - render_container_set_overlay(render_container_get_screen(screen), effect_bitmap); + screen->container().set_overlay(effect_bitmap); global_free(tempstr); } diff --git a/src/osd/sdl/window.c b/src/osd/sdl/window.c index ded2b3d8b18..cc2493eaf00 100644 --- a/src/osd/sdl/window.c +++ b/src/osd/sdl/window.c @@ -347,14 +347,14 @@ void sdlwindow_blit_surface_size(sdl_window_info *window, int window_width, int INT32 target_height = window_height; // start with the minimum size - render_target_get_minimum_size(window->target, &newwidth, &newheight); + window->target->compute_minimum_size(newwidth, newheight); // compute the appropriate visible area if we're trying to keepaspect if (video_config.keepaspect) { // make sure the monitor is up-to-date sdlvideo_monitor_refresh(window->monitor); - render_target_compute_visible_area(window->target, target_width, target_height, sdlvideo_monitor_get_aspect(window->monitor), render_target_get_orientation(window->target), &target_width, &target_height); + window->target->compute_visible_area(target_width, target_height, sdlvideo_monitor_get_aspect(window->monitor), window->target->orientation(), target_width, target_height); desired_aspect = (float)target_width / (float)target_height; } @@ -406,7 +406,7 @@ void sdlwindow_blit_surface_size(sdl_window_info *window, int window_width, int } //FIXME: really necessary to distinguish for yuv_modes ? - if ((render_target_get_layer_config(window->target) & LAYER_CONFIG_ZOOM_TO_SCREEN) + if (window->target->zoom_to_screen() && (window->scale_mode == VIDEO_SCALE_MODE_NONE )) newwidth = window_width; @@ -695,12 +695,7 @@ int sdlwindow_video_window_create(running_machine *machine, int index, sdl_monit window->rendered_event = osd_event_alloc(FALSE, TRUE); // load the layout - window->target = render_target_alloc(machine, NULL, FALSE); - if (window->target == NULL) - { - osd_free(wp); - goto error; - } + window->target = machine->render().target_alloc(); // set the specific view sprintf(option, SDLOPTION_VIEW("%d"), index); @@ -789,8 +784,7 @@ static void sdlwindow_video_window_destroy(running_machine *machine, sdl_window_ execute_async_wait(&sdlwindow_video_window_destroy_wt, &wp); // free the render target, after the textures! - if (window->target != NULL) - render_target_free(window->target); + window->machine->render().target_free(window->target); // free the event osd_event_free(window->rendered_event); @@ -813,7 +807,7 @@ static void pick_best_mode(sdl_window_info *window, int *fswidth, int *fsheight) float size_score, best_score = 0.0f; // determine the minimum width/height for the selected target - render_target_get_minimum_size(window->target, &minimum_width, &minimum_height); + window->target->compute_minimum_size(minimum_width, minimum_height); // use those as the target for now target_width = minimum_width * MAX(1, window->prescale); @@ -880,7 +874,7 @@ static void pick_best_mode(sdl_window_info *window, int *fswidth, int *fsheight) SDL_Rect **modes; // determine the minimum width/height for the selected target - render_target_get_minimum_size(window->target, &minimum_width, &minimum_height); + window->target->compute_minimum_size(minimum_width, minimum_height); // use those as the target for now target_width = minimum_width * MAX(1, window->prescale); @@ -966,7 +960,7 @@ void sdlwindow_video_window_update(running_machine *machine, sdl_window_info *wi int tempwidth, tempheight; // see if the games video mode has changed - render_target_get_minimum_size(window->target, &tempwidth, &tempheight); + window->target->compute_minimum_size(tempwidth, tempheight); if (tempwidth != window->minwidth || tempheight != window->minheight) { window->minwidth = tempwidth; @@ -1026,7 +1020,7 @@ static void set_starting_view(running_machine *machine, int index, sdl_window_in viewindex = video_get_view_for_target(machine, window->target, view, index, video_config.numscreens); // set the view - render_target_set_view(window->target, viewindex); + window->target->set_view(viewindex); window->start_viewscreen=viewindex; } @@ -1208,21 +1202,21 @@ static void constrain_to_aspect_ratio(sdl_window_info *window, int *window_width { case WMSZ_BOTTOM: case WMSZ_TOP: - render_target_compute_visible_area(window->target, 10000, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(10000, propheight, pixel_aspect, window->target->orientation(), propwidth, propheight); break; case WMSZ_LEFT: case WMSZ_RIGHT: - render_target_compute_visible_area(window->target, propwidth, 10000, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(propwidth, 10000, pixel_aspect, window->target->orientation(), propwidth, propheight); break; default: - render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(propwidth, propheight, pixel_aspect, window->target->orientation(), propwidth, propheight); break; } // get the minimum width/height for the current layout - render_target_get_minimum_size(window->target, &minwidth, &minheight); + window->target->compute_minimum_size(minwidth, minheight); // clamp against the absolute minimum propwidth = MAX(propwidth, MIN_WINDOW_DIM); @@ -1255,7 +1249,7 @@ static void constrain_to_aspect_ratio(sdl_window_info *window, int *window_width propheight = MIN(propheight, maxheight); // compute the visible area based on the proposed rectangle - render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &viswidth, &visheight); + window->target->compute_visible_area(propwidth, propheight, pixel_aspect, window->target->orientation(), viswidth, visheight); *window_width = viswidth; *window_height = visheight; @@ -1272,7 +1266,7 @@ static void get_min_bounds(sdl_window_info *window, int *window_width, int *wind INT32 minwidth, minheight; // get the minimum target size - render_target_get_minimum_size(window->target, &minwidth, &minheight); + window->target->compute_minimum_size(minwidth, minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index 05369289eac..2c5e4200271 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -45,7 +45,7 @@ struct _sdl_window_info int (*create)(sdl_window_info *window, int width, int height); void (*resize)(sdl_window_info *window, int width, int height); int (*draw)(sdl_window_info *window, UINT32 dc, int update); - const render_primitive_list *(*get_primitives)(sdl_window_info *window); + render_primitive_list &(*get_primitives)(sdl_window_info *window); int (*xy_to_render_target)(sdl_window_info *window, int x, int y, int *xt, int *yt); void (*destroy_all_textures)(sdl_window_info *window); void (*destroy)(sdl_window_info *window); @@ -71,7 +71,7 @@ struct _sdl_window_info // rendering info osd_event * rendered_event; render_target * target; - const render_primitive_list *primlist; + render_primitive_list *primlist; // drawing data void * dxdata; diff --git a/src/osd/windows/debugwin.c b/src/osd/windows/debugwin.c index fe221d79211..5160732f923 100644 --- a/src/osd/windows/debugwin.c +++ b/src/osd/windows/debugwin.c @@ -607,7 +607,7 @@ static void debugwin_window_free(debugwin_info *info) for (viewnum = 0; viewnum < ARRAY_LENGTH(info->view); viewnum++) if (info->view[viewnum].view != NULL) { - info->machine->m_debug_view->free_view(*info->view[viewnum].view); + info->machine->debug_view().free_view(*info->view[viewnum].view); info->view[viewnum].view = NULL; } @@ -851,7 +851,7 @@ static int debugwin_view_create(debugwin_info *info, int which, debug_view_type goto cleanup; // create the debug view - view->view = info->machine->m_debug_view->alloc_view(type, debugwin_view_update, view); + view->view = info->machine->debug_view().alloc_view(type, debugwin_view_update, view); if (view->view == NULL) goto cleanup; @@ -859,7 +859,7 @@ static int debugwin_view_create(debugwin_info *info, int which, debug_view_type cleanup: if (view->view) - info->machine->m_debug_view->free_view(*view->view); + info->machine->debug_view().free_view(*view->view); if (view->hscroll) DestroyWindow(view->hscroll); if (view->vscroll) @@ -1468,7 +1468,7 @@ static LRESULT CALLBACK debugwin_view_proc(HWND wnd, UINT message, WPARAM wparam debug_view_xy topleft = info->view->visible_position(); topleft.x = debugwin_view_process_scroll(info, LOWORD(wparam), (HWND)lparam); info->view->set_visible_position(topleft); - info->owner->machine->m_debug_view->flush_osd_updates(); + info->owner->machine->debug_view().flush_osd_updates(); break; } @@ -1478,7 +1478,7 @@ static LRESULT CALLBACK debugwin_view_proc(HWND wnd, UINT message, WPARAM wparam debug_view_xy topleft = info->view->visible_position(); topleft.y = debugwin_view_process_scroll(info, LOWORD(wparam), (HWND)lparam); info->view->set_visible_position(topleft); - info->owner->machine->m_debug_view->flush_osd_updates(); + info->owner->machine->debug_view().flush_osd_updates(); break; } @@ -2484,11 +2484,11 @@ void console_create_window(running_machine *machine) cleanup: if (info->view[2].view) - machine->m_debug_view->free_view(*info->view[2].view); + machine->debug_view().free_view(*info->view[2].view); if (info->view[1].view) - machine->m_debug_view->free_view(*info->view[1].view); + machine->debug_view().free_view(*info->view[1].view); if (info->view[0].view) - machine->m_debug_view->free_view(*info->view[0].view); + machine->debug_view().free_view(*info->view[0].view); } diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c index 743b84794df..320ff3d2cd6 100644 --- a/src/osd/windows/drawd3d.c +++ b/src/osd/windows/drawd3d.c @@ -439,7 +439,7 @@ INLINE void reset_render_states(d3d_info *d3d) static void drawd3d_exit(void); static int drawd3d_window_init(win_window_info *window); static void drawd3d_window_destroy(win_window_info *window); -static const render_primitive_list *drawd3d_window_get_primitives(win_window_info *window); +static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window); static int drawd3d_window_draw(win_window_info *window, HDC dc, int update); // devices @@ -591,7 +591,7 @@ static void drawd3d_window_destroy(win_window_info *window) // drawd3d_window_get_primitives //============================================================ -static const render_primitive_list *drawd3d_window_get_primitives(win_window_info *window) +static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window) { d3d_info *d3d = (d3d_info *)window->drawdata; RECT client; @@ -599,10 +599,10 @@ static const render_primitive_list *drawd3d_window_get_primitives(win_window_inf GetClientRectExceptMenu(window->hwnd, &client, window->fullscreen); if (rect_width(&client) > 0 && rect_height(&client) > 0) { - render_target_set_bounds(window->target, rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); - render_target_set_max_update_rate(window->target, (d3d->refresh == 0) ? d3d->origmode.RefreshRate : d3d->refresh); + window->target->set_bounds(rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); + window->target->set_max_update_rate((d3d->refresh == 0) ? d3d->origmode.RefreshRate : d3d->refresh); } - return render_target_get_primitives(window->target); + return &window->target->get_primitives(); } @@ -614,7 +614,7 @@ static const render_primitive_list *drawd3d_window_get_primitives(win_window_inf static int drawd3d_window_draw(win_window_info *window, HDC dc, int update) { d3d_info *d3d = (d3d_info *)window->drawdata; - const render_primitive *prim; + render_primitive *prim; HRESULT result; // if we haven't been created, just punt @@ -644,8 +644,8 @@ static int drawd3d_window_draw(win_window_info *window, HDC dc, int update) mtlog_add("drawd3d_window_draw: begin"); // first update any textures - osd_lock_acquire(window->primlist->lock); - for (prim = window->primlist->head; prim != NULL; prim = prim->next) + window->primlist->acquire_lock(); + for (prim = window->primlist->first(); prim != NULL; prim = prim->next()) if (prim->texture.base != NULL) texture_update(d3d, prim); @@ -658,19 +658,22 @@ mtlog_add("drawd3d_window_draw: begin_scene"); // loop over primitives mtlog_add("drawd3d_window_draw: primitive loop begin"); - for (prim = window->primlist->head; prim != NULL; prim = prim->next) + for (prim = window->primlist->first(); prim != NULL; prim = prim->next()) switch (prim->type) { - case RENDER_PRIMITIVE_LINE: + case render_primitive::LINE: draw_line(d3d, prim); break; - case RENDER_PRIMITIVE_QUAD: + case render_primitive::QUAD: draw_quad(d3d, prim); break; + + default: + throw emu_fatalerror("Unexpected render_primitive type"); } mtlog_add("drawd3d_window_draw: primitive loop end"); - osd_lock_release(window->primlist->lock); + window->primlist->release_lock(); // flush any pending polygons mtlog_add("drawd3d_window_draw: flush_pending begin"); @@ -796,7 +799,7 @@ try_again: mame_printf_verbose("Direct3D: Device created at %dx%d\n", d3d->width, d3d->height); // set the max texture size - render_target_set_max_texture_size(window->target, d3d->texture_max_width, d3d->texture_max_height); + window->target->set_max_texture_size(d3d->texture_max_width, d3d->texture_max_height); mame_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)d3d->texture_max_width, (int)d3d->texture_max_height); // set the gamma if we need to @@ -1288,7 +1291,7 @@ static void pick_best_mode(win_window_info *window) // note: technically we should not be calling this from an alternate window // thread; however, it is only done during init time, and the init code on // the main thread is waiting for us to finish, so it is safe to do so here - render_target_get_minimum_size(window->target, &minwidth, &minheight); + window->target->compute_minimum_size(minwidth, minheight); // use those as the target for now target_width = minwidth; diff --git a/src/osd/windows/drawdd.c b/src/osd/windows/drawdd.c index 7320471c27b..afdc06fd821 100644 --- a/src/osd/windows/drawdd.c +++ b/src/osd/windows/drawdd.c @@ -178,7 +178,7 @@ INLINE int better_mode(int width0, int height0, int width1, int height1, float d static void drawdd_exit(void); static int drawdd_window_init(win_window_info *window); static void drawdd_window_destroy(win_window_info *window); -static const render_primitive_list *drawdd_window_get_primitives(win_window_info *window); +static render_primitive_list *drawdd_window_get_primitives(win_window_info *window); static int drawdd_window_draw(win_window_info *window, HDC dc, int update); // surface management @@ -201,14 +201,14 @@ static void get_adapter_for_monitor(dd_info *dd, win_monitor_info *monitor); static void pick_best_mode(win_window_info *window); // rendering -static void drawdd_rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_bgr888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb565_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb555_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb888_nr_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_bgr888_nr_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb565_nr_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb555_nr_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_bgr888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb565_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb555_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb888_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_bgr888_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb565_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawdd_rgb555_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); @@ -327,15 +327,15 @@ static void drawdd_window_destroy(win_window_info *window) // drawdd_window_get_primitives //============================================================ -static const render_primitive_list *drawdd_window_get_primitives(win_window_info *window) +static render_primitive_list *drawdd_window_get_primitives(win_window_info *window) { dd_info *dd = (dd_info *)window->drawdata; compute_blit_surface_size(window); - render_target_set_bounds(window->target, dd->blitwidth, dd->blitheight, 0); - render_target_set_max_update_rate(window->target, (dd->refresh == 0) ? dd->origmode.dwRefreshRate : dd->refresh); + window->target->set_bounds(dd->blitwidth, dd->blitheight, 0); + window->target->set_max_update_rate((dd->refresh == 0) ? dd->origmode.dwRefreshRate : dd->refresh); - return render_target_get_primitives(window->target); + return &window->target->get_primitives(); } @@ -347,7 +347,7 @@ static const render_primitive_list *drawdd_window_get_primitives(win_window_info static int drawdd_window_draw(win_window_info *window, HDC dc, int update) { dd_info *dd = (dd_info *)window->drawdata; - const render_primitive *prim; + render_primitive *prim; int usemembuffer = FALSE; HRESULT result; @@ -386,10 +386,10 @@ static int drawdd_window_draw(win_window_info *window, HDC dc, int update) } // render to it - osd_lock_acquire(window->primlist->lock); + window->primlist->acquire_lock(); // scan the list of primitives for tricky stuff - for (prim = window->primlist->head; prim != NULL; prim = prim->next) + for (prim = window->primlist->first(); prim != NULL; prim = prim->next()) if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE || (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32)) { @@ -405,10 +405,10 @@ static int drawdd_window_draw(win_window_info *window, HDC dc, int update) // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { - case 0x00ff0000: drawdd_rgb888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0x000000ff: drawdd_bgr888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0xf800: drawdd_rgb565_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0x7c00: drawdd_rgb555_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x00ff0000: drawdd_rgb888_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x000000ff: drawdd_bgr888_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0xf800: drawdd_rgb565_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x7c00: drawdd_rgb555_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; @@ -441,16 +441,16 @@ static int drawdd_window_draw(win_window_info *window, HDC dc, int update) // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { - case 0x00ff0000: drawdd_rgb888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; - case 0x000000ff: drawdd_bgr888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; - case 0xf800: drawdd_rgb565_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; - case 0x7c00: drawdd_rgb555_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; + case 0x00ff0000: drawdd_rgb888_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; + case 0x000000ff: drawdd_bgr888_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; + case 0xf800: drawdd_rgb565_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; + case 0x7c00: drawdd_rgb555_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; } } - osd_lock_release(window->primlist->lock); + window->primlist->release_lock(); // unlock and blit result = IDirectDrawSurface7_Unlock(dd->blit, NULL); @@ -879,7 +879,7 @@ static void compute_blit_surface_size(win_window_info *window) RECT client; // start with the minimum size - render_target_get_minimum_size(window->target, &newwidth, &newheight); + window->target->compute_minimum_size(newwidth, newheight); // get the window's client rectangle GetClientRect(window->hwnd, &client); @@ -909,7 +909,7 @@ static void compute_blit_surface_size(win_window_info *window) if (video_config.keepaspect) { win_monitor_info *monitor = winwindow_video_window_monitor(window, NULL); - render_target_compute_visible_area(window->target, target_width, target_height, winvideo_monitor_get_aspect(monitor), render_target_get_orientation(window->target), &target_width, &target_height); + window->target->compute_visible_area(target_width, target_height, winvideo_monitor_get_aspect(monitor), window->target->orientation(), target_width, target_height); desired_aspect = (float)target_width / (float)target_height; } @@ -1054,7 +1054,7 @@ static void blit_to_primary(win_window_info *window, int srcwidth, int srcheight else if (video_config.keepaspect) { // compute the appropriate visible area - render_target_compute_visible_area(window->target, rect_width(&outer), rect_height(&outer), winvideo_monitor_get_aspect(monitor), render_target_get_orientation(window->target), &dstwidth, &dstheight); + window->target->compute_visible_area(rect_width(&outer), rect_height(&outer), winvideo_monitor_get_aspect(monitor), window->target->orientation(), dstwidth, dstheight); } // center within @@ -1325,7 +1325,7 @@ static void pick_best_mode(win_window_info *window) // note: technically we should not be calling this from an alternate window // thread; however, it is only done during init time, and the init code on // the main thread is waiting for us to finish, so it is safe to do so here - render_target_get_minimum_size(window->target, &einfo.minimum_width, &einfo.minimum_height); + window->target->compute_minimum_size(einfo.minimum_width, einfo.minimum_height); // use those as the target for now einfo.target_width = einfo.minimum_width * MAX(1, video_config.prescale); diff --git a/src/osd/windows/drawgdi.c b/src/osd/windows/drawgdi.c index 0f9f7425bcb..2213a55ada2 100644 --- a/src/osd/windows/drawgdi.c +++ b/src/osd/windows/drawgdi.c @@ -75,11 +75,11 @@ struct _gdi_info static void drawgdi_exit(void); static int drawgdi_window_init(win_window_info *window); static void drawgdi_window_destroy(win_window_info *window); -static const render_primitive_list *drawgdi_window_get_primitives(win_window_info *window); +static render_primitive_list *drawgdi_window_get_primitives(win_window_info *window); static int drawgdi_window_draw(win_window_info *window, HDC dc, int update); // rendering -static void drawgdi_rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); +static void drawgdi_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); @@ -172,12 +172,12 @@ static void drawgdi_window_destroy(win_window_info *window) // drawgdi_window_get_primitives //============================================================ -static const render_primitive_list *drawgdi_window_get_primitives(win_window_info *window) +static render_primitive_list *drawgdi_window_get_primitives(win_window_info *window) { RECT client; GetClientRect(window->hwnd, &client); - render_target_set_bounds(window->target, rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); - return render_target_get_primitives(window->target); + window->target->set_bounds(rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); + return &window->target->get_primitives(); } @@ -213,9 +213,9 @@ static int drawgdi_window_draw(win_window_info *window, HDC dc, int update) } // draw the primitives to the bitmap - osd_lock_acquire(window->primlist->lock); - drawgdi_rgb888_draw_primitives(window->primlist->head, gdi->bmdata, width, height, pitch); - osd_lock_release(window->primlist->lock); + window->primlist->acquire_lock(); + drawgdi_rgb888_draw_primitives(*window->primlist, gdi->bmdata, width, height, pitch); + window->primlist->release_lock(); // fill in bitmap-specific info gdi->bminfo.bmiHeader.biWidth = pitch; diff --git a/src/osd/windows/drawnone.c b/src/osd/windows/drawnone.c index 07cb67f345f..3980b2994d6 100644 --- a/src/osd/windows/drawnone.c +++ b/src/osd/windows/drawnone.c @@ -59,7 +59,7 @@ static void drawnone_exit(void); static int drawnone_window_init(win_window_info *window); static void drawnone_window_destroy(win_window_info *window); -static const render_primitive_list *drawnone_window_get_primitives(win_window_info *window); +static render_primitive_list *drawnone_window_get_primitives(win_window_info *window); static int drawnone_window_draw(win_window_info *window, HDC dc, int update); @@ -116,12 +116,12 @@ static void drawnone_window_destroy(win_window_info *window) // drawnone_window_get_primitives //============================================================ -static const render_primitive_list *drawnone_window_get_primitives(win_window_info *window) +static render_primitive_list *drawnone_window_get_primitives(win_window_info *window) { RECT client; GetClientRect(window->hwnd, &client); - render_target_set_bounds(window->target, rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); - return render_target_get_primitives(window->target); + window->target->set_bounds(rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor)); + return &window->target->get_primitives(); } diff --git a/src/osd/windows/video.c b/src/osd/windows/video.c index ad3bdf67dc4..35865870473 100644 --- a/src/osd/windows/video.c +++ b/src/osd/windows/video.c @@ -490,7 +490,7 @@ static void load_effect_overlay(running_machine *machine, const char *filename) // set the overlay on all screens for (screen_device *screen = screen_first(*machine); screen != NULL; screen = screen_next(screen)) - render_container_set_overlay(render_container_get_screen(screen), effect_bitmap); + screen->container().set_overlay(effect_bitmap); global_free(tempstr); } diff --git a/src/osd/windows/window.c b/src/osd/windows/window.c index 3dacac370fe..b9ee2aabf74 100644 --- a/src/osd/windows/window.c +++ b/src/osd/windows/window.c @@ -636,18 +636,16 @@ void winwindow_video_window_create(running_machine *machine, int index, win_moni window->render_lock = osd_lock_alloc(); // load the layout - window->target = render_target_alloc(machine, NULL, 0); - if (window->target == NULL) - fatalerror("Error creating render target for window %d", index); + window->target = machine->render().target_alloc(); // set the specific view sprintf(option, "view%d", index); set_starting_view(index, window, options_get_string(machine->options(), option)); // remember the current values in case they change - window->targetview = render_target_get_view(window->target); - window->targetorient = render_target_get_orientation(window->target); - window->targetlayerconfig = render_target_get_layer_config(window->target); + window->targetview = window->target->view(); + window->targetorient = window->target->orientation(); + window->targetlayerconfig = window->target->layer_config(); // make the window title if (video_config.numscreens == 1) @@ -702,8 +700,7 @@ static void winwindow_video_window_destroy(win_window_info *window) SendMessage(window->hwnd, WM_USER_SELF_TERMINATE, 0, 0); // free the render target - if (window->target != NULL) - render_target_free(window->target); + window->machine->render().target_free(window->target); // free the lock osd_lock_free(window->render_lock); @@ -728,9 +725,9 @@ void winwindow_video_window_update(win_window_info *window) mtlog_add("winwindow_video_window_update: begin"); // see if the target has changed significantly in window mode - targetview = render_target_get_view(window->target); - targetorient = render_target_get_orientation(window->target); - targetlayerconfig = render_target_get_layer_config(window->target); + targetview = window->target->view(); + targetorient = window->target->orientation(); + targetlayerconfig = window->target->layer_config(); if (targetview != window->targetview || targetorient != window->targetorient || targetlayerconfig != window->targetlayerconfig) { window->targetview = targetview; @@ -763,7 +760,7 @@ void winwindow_video_window_update(win_window_info *window) // only render if we were able to get the lock if (got_lock) { - const render_primitive_list *primlist; + render_primitive_list *primlist; mtlog_add("winwindow_video_window_update: got lock"); @@ -873,7 +870,7 @@ static void set_starting_view(int index, win_window_info *window, const char *vi viewindex = video_get_view_for_target(window->machine, window->target, view, index, video_config.numscreens); // set the view - render_target_set_view(window->target, viewindex); + window->target->set_view(viewindex); } @@ -1361,7 +1358,7 @@ LRESULT CALLBACK winwindow_video_window_proc(HWND wnd, UINT message, WPARAM wpar HDC hdc = GetDC(wnd); mtlog_add("winwindow_video_window_proc: WM_USER_REDRAW begin"); - window->primlist = (const render_primitive_list *)lparam; + window->primlist = (render_primitive_list *)lparam; draw_video_contents(window, hdc, FALSE); mtlog_add("winwindow_video_window_proc: WM_USER_REDRAW end"); @@ -1480,21 +1477,21 @@ static void constrain_to_aspect_ratio(win_window_info *window, RECT *rect, int a { case WMSZ_BOTTOM: case WMSZ_TOP: - render_target_compute_visible_area(window->target, 10000, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(10000, propheight, pixel_aspect, window->target->orientation(), propwidth, propheight); break; case WMSZ_LEFT: case WMSZ_RIGHT: - render_target_compute_visible_area(window->target, propwidth, 10000, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(propwidth, 10000, pixel_aspect, window->target->orientation(), propwidth, propheight); break; default: - render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); + window->target->compute_visible_area(propwidth, propheight, pixel_aspect, window->target->orientation(), propwidth, propheight); break; } // get the minimum width/height for the current layout - render_target_get_minimum_size(window->target, &minwidth, &minheight); + window->target->compute_minimum_size(minwidth, minheight); // clamp against the absolute minimum propwidth = MAX(propwidth, MIN_WINDOW_DIM); @@ -1527,7 +1524,7 @@ static void constrain_to_aspect_ratio(win_window_info *window, RECT *rect, int a propheight = MIN(propheight, maxheight); // compute the visible area based on the proposed rectangle - render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &viswidth, &visheight); + window->target->compute_visible_area(propwidth, propheight, pixel_aspect, window->target->orientation(), viswidth, visheight); // compute the adjustments we need to make adjwidth = (viswidth + extrawidth) - rect_width(rect); @@ -1576,7 +1573,7 @@ static void get_min_bounds(win_window_info *window, RECT *bounds, int constrain) assert(GetCurrentThreadId() == window_threadid); // get the minimum target size - render_target_get_minimum_size(window->target, &minwidth, &minheight); + window->target->compute_minimum_size(minwidth, minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index 6d771eff73a..7e743828bd3 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -101,7 +101,7 @@ struct _win_window_info int targetview; int targetorient; int targetlayerconfig; - const render_primitive_list *primlist; + render_primitive_list *primlist; // input info DWORD lastclicktime; @@ -121,7 +121,7 @@ struct _win_draw_callbacks void (*exit)(void); int (*window_init)(win_window_info *window); - const render_primitive_list *(*window_get_primitives)(win_window_info *window); + render_primitive_list *(*window_get_primitives)(win_window_info *window); int (*window_draw)(win_window_info *window, HDC dc, int update); void (*window_destroy)(win_window_info *window); };