Introduced a comparable "osd_renderer" interface like it now exists for

SDL to mainline. 
Ultimately, this will allow renderers to be placed in modules\renderer
and e.g. allow the opengl renderer to be used in mainline or the d3d
renderer to be used in sdlmame. (nw)
This commit is contained in:
couriersud 2015-02-05 23:24:15 +01:00
parent 388875c61d
commit 950b1b0514
9 changed files with 579 additions and 529 deletions

View File

@ -224,7 +224,7 @@ void shaders::window_save()
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture); HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture);
if (result != D3D_OK) if (result != D3D_OK)
@ -276,7 +276,7 @@ void shaders::avi_update_snap(surface *surface)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
@ -326,7 +326,7 @@ void shaders::render_snapshot(surface *surface)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
@ -519,7 +519,7 @@ void shaders::begin_avi_recording(const char *name)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
// stop any existing recording // stop any existing recording
end_avi_recording(); end_avi_recording();
@ -678,7 +678,7 @@ void shaders::set_texture(texture_info *texture)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
if(texture != NULL) if(texture != NULL)
{ {
@ -820,7 +820,7 @@ void shaders::init_fsfx_quad(void *vertbuf)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
// get a pointer to the vertex buffer // get a pointer to the vertex buffer
fsfx_vertices = (vertex *)vertbuf; fsfx_vertices = (vertex *)vertbuf;
@ -892,7 +892,7 @@ int shaders::create_resources(bool reset)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return 0; return 0;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer); HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
@ -1066,7 +1066,7 @@ void shaders::begin_draw()
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
curr_effect = default_effect; curr_effect = default_effect;
@ -1101,7 +1101,7 @@ void shaders::begin_frame()
void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type, void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
UINT32 prim_index, UINT32 prim_count, int dstw, int dsth) UINT32 prim_index, UINT32 prim_count, int dstw, int dsth)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst); HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
@ -1146,7 +1146,7 @@ void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYP
void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type, void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
UINT32 prim_index, UINT32 prim_count) UINT32 prim_index, UINT32 prim_count)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst); HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
@ -1231,7 +1231,7 @@ void shaders::init_effect_info(poly_info *poly)
if (!master_enable || !d3dintf->post_fx_available) if (!master_enable || !d3dintf->post_fx_available)
return; return;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
texture_info *texture = poly->get_texture(); texture_info *texture = poly->get_texture();
if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && texture != NULL) if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && texture != NULL)
@ -1308,7 +1308,7 @@ cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int hei
void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta) void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
if(options->yiq_enable) if(options->yiq_enable)
@ -1370,7 +1370,7 @@ void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta)
void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims) void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = color_effect; curr_effect = color_effect;
@ -1398,7 +1398,7 @@ void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &s
void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims) void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = prescale_effect; curr_effect = prescale_effect;
@ -1426,7 +1426,7 @@ void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims
void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims) void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = deconverge_effect; curr_effect = deconverge_effect;
@ -1454,7 +1454,7 @@ void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, v
void shaders::defocus_pass(render_target *rt, vec2f &texsize) void shaders::defocus_pass(render_target *rt, vec2f &texsize)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
// Defocus pass 1 // Defocus pass 1
@ -1503,7 +1503,7 @@ void shaders::defocus_pass(render_target *rt, vec2f &texsize)
void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable) void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = phosphor_effect; curr_effect = phosphor_effect;
@ -1561,7 +1561,7 @@ void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize,
void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum) void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = post_effect; curr_effect = post_effect;
@ -1616,7 +1616,7 @@ void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec
void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum) void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = post_effect; curr_effect = post_effect;
@ -1650,7 +1650,7 @@ void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta,
void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum) void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
UINT num_passes = 0; UINT num_passes = 0;
curr_effect = downsample_effect; curr_effect = downsample_effect;
@ -1755,7 +1755,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
return; return;
UINT num_passes = 0; UINT num_passes = 0;
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
curr_texture = poly->get_texture(); curr_texture = poly->get_texture();
if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL) if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL)
@ -2080,14 +2080,14 @@ render_target* shaders::get_vector_target()
return NULL; return NULL;
} }
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
} }
void shaders::create_vector_target(render_primitive *prim) void shaders::create_vector_target(render_primitive *prim)
{ {
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
if (!add_render_target(d3d, NULL, d3d->get_width(), d3d->get_height(), 1, 1)) if (!add_render_target(d3d, NULL, d3d->get_width(), d3d->get_height(), 1, 1))
{ {
vector_enable = false; vector_enable = false;
@ -2202,7 +2202,7 @@ bool shaders::register_texture(texture_info *texture)
enumerate_screens(); enumerate_screens();
renderer *d3d = (renderer *)window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(window->m_renderer);
int hlsl_prescale_x = prescale_force_x; int hlsl_prescale_x = prescale_force_x;
int hlsl_prescale_y = prescale_force_y; int hlsl_prescale_y = prescale_force_y;
@ -2994,7 +2994,7 @@ void uniform::update()
} }
shaders *shadersys = m_shader->m_shaders; shaders *shadersys = m_shader->m_shaders;
renderer *d3d = (renderer *)shadersys->window->m_drawdata; renderer *d3d = dynamic_cast<renderer *>(shadersys->window->m_renderer);
hlsl_options *options = shadersys->options; hlsl_options *options = shadersys->options;
switch(m_id) switch(m_id)
@ -3422,7 +3422,7 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp
UINT32 origflags = file.openflags(); UINT32 origflags = file.openflags();
// handle defaults // handle defaults
const char *snapname = templ ? templ : d3d->get_window()->machine().options().snap_name(); const char *snapname = templ ? templ : d3d->window().machine().options().snap_name();
if (snapname == NULL || snapname[0] == 0) if (snapname == NULL || snapname[0] == 0)
snapname = "%g/%i"; snapname = "%g/%i";
@ -3469,7 +3469,7 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp
snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3); snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3);
// verify that there is such a device for this system // verify that there is such a device for this system
image_interface_iterator iter(d3d->get_window()->machine().root_device()); image_interface_iterator iter(d3d->window().machine().root_device());
for (device_image_interface *image = iter.first(); image != NULL; iter.next()) for (device_image_interface *image = iter.first(); image != NULL; iter.next())
{ {
// get the device name // get the device name
@ -3506,7 +3506,7 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp
// substitute path and gamename up front // substitute path and gamename up front
snapstr.replace(0, "/", PATH_SEPARATOR); snapstr.replace(0, "/", PATH_SEPARATOR);
snapstr.replace(0, "%g", d3d->get_window()->machine().basename()); snapstr.replace(0, "%g", d3d->window().machine().basename());
// determine if the template has an index; if not, we always use the same name // determine if the template has an index; if not, we always use the same name
astring fname; astring fname;

View File

@ -22,32 +22,52 @@
#include <bgfxplatform.h> #include <bgfxplatform.h>
#include <bgfx.h> #include <bgfx.h>
class renderer_bgfx : public osd_renderer
{
public:
renderer_bgfx(win_window_info *window)
: osd_renderer(window, FLAG_NONE) { }
virtual ~renderer_bgfx() { }
virtual int init();
virtual render_primitive_list *get_primitives();
virtual int draw(HDC dc, int update);
virtual void save() {};
virtual void record() {};
virtual void toggle_fsfx() {};
virtual void destroy();
private:
};
//============================================================ //============================================================
// PROTOTYPES // PROTOTYPES
//============================================================ //============================================================
// core functions // core functions
static void drawbgfx_exit(void); static void drawbgfx_exit(void);
static int drawbgfx_window_init(win_window_info *window);
static void drawbgfx_window_destroy(win_window_info *window);
static render_primitive_list *drawbgfx_window_get_primitives(win_window_info *window);
static int drawbgfx_window_draw(win_window_info *window, HDC dc, int update);
//============================================================
// drawnone_create
//============================================================
osd_renderer *drawbgfx_create(win_window_info *window)
{
return global_alloc(renderer_bgfx(window));
}
//============================================================ //============================================================
// drawbgfx_init // drawbgfx_init
//============================================================ //============================================================
int drawbgfx_init(running_machine &machine, win_draw_callbacks *callbacks) int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks)
{ {
// fill in the callbacks // fill in the callbacks
memset(callbacks, 0, sizeof(*callbacks)); memset(callbacks, 0, sizeof(*callbacks));
callbacks->exit = drawbgfx_exit; callbacks->exit = drawbgfx_exit;
callbacks->window_init = drawbgfx_window_init; callbacks->create = drawbgfx_create;
callbacks->window_get_primitives = drawbgfx_window_get_primitives;
callbacks->window_draw = drawbgfx_window_draw;
callbacks->window_destroy = drawbgfx_window_destroy;
return 0; return 0;
} }
@ -67,19 +87,18 @@ static void drawbgfx_exit(void)
// drawbgfx_window_init // drawbgfx_window_init
//============================================================ //============================================================
static int drawbgfx_window_init(win_window_info *window) int renderer_bgfx::init()
{ {
RECT client; RECT client;
GetClientRect(window->m_hwnd, &client); GetClientRect(window().m_hwnd, &client);
bgfx::winSetHwnd(window->m_hwnd); bgfx::winSetHwnd(window().m_hwnd);
bgfx::init(); bgfx::init();
bgfx::reset(rect_width(&client), rect_height(&client), BGFX_RESET_VSYNC); bgfx::reset(rect_width(&client), rect_height(&client), BGFX_RESET_VSYNC);
// Enable debug text. // Enable debug text.
bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT); bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT);
window->m_drawdata = window->m_hwnd;
return 0; return 0;
} }
@ -89,11 +108,10 @@ static int drawbgfx_window_init(win_window_info *window)
// drawbgfx_window_destroy // drawbgfx_window_destroy
//============================================================ //============================================================
static void drawbgfx_window_destroy(win_window_info *window) void renderer_bgfx::destroy()
{ {
// Shutdown bgfx. // Shutdown bgfx.
bgfx::shutdown(); bgfx::shutdown();
window->m_drawdata = NULL;
} }
@ -102,12 +120,12 @@ static void drawbgfx_window_destroy(win_window_info *window)
// drawbgfx_window_get_primitives // drawbgfx_window_get_primitives
//============================================================ //============================================================
static render_primitive_list *drawbgfx_window_get_primitives(win_window_info *window) render_primitive_list *renderer_bgfx::get_primitives()
{ {
RECT client; RECT client;
GetClientRect(window->m_hwnd, &client); GetClientRect(window().m_hwnd, &client);
window->m_target->set_bounds(rect_width(&client), rect_height(&client), window->m_monitor->get_aspect()); window().m_target->set_bounds(rect_width(&client), rect_height(&client), window().m_monitor->get_aspect());
return &window->m_target->get_primitives(); return &window().m_target->get_primitives();
} }
@ -116,10 +134,10 @@ static render_primitive_list *drawbgfx_window_get_primitives(win_window_info *wi
// drawbgfx_window_draw // drawbgfx_window_draw
//============================================================ //============================================================
static int drawbgfx_window_draw(win_window_info *window, HDC dc, int update) int renderer_bgfx::draw(HDC dc, int update)
{ {
RECT client; RECT client;
GetClientRect(window->m_hwnd, &client); GetClientRect(window().m_hwnd, &client);
bgfx::setViewClear(0 bgfx::setViewClear(0
, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
@ -134,10 +152,10 @@ static int drawbgfx_window_draw(win_window_info *window, HDC dc, int update)
// if no other draw calls are submitted to view 0. // if no other draw calls are submitted to view 0.
bgfx::submit(0); bgfx::submit(0);
window->m_primlist->acquire_lock(); window().m_primlist->acquire_lock();
// now draw // now draw
for (render_primitive *prim = window->m_primlist->first(); prim != NULL; prim = prim->next()) for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
{ {
switch (prim->type) switch (prim->type)
{ {
@ -219,7 +237,7 @@ static int drawbgfx_window_draw(win_window_info *window, HDC dc, int update)
} }
} }
window->m_primlist->release_lock(); window().m_primlist->release_lock();
// Advance to next frame. Rendering thread will be kicked to // Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives. // process submitted rendering primitives.
bgfx::frame(); bgfx::frame();

View File

@ -179,28 +179,16 @@ static d3d::base * d3dintf; // FIX ME
// core functions // core functions
static void drawd3d_exit(void); static void drawd3d_exit(void);
static int drawd3d_window_init(win_window_info *window);
static void drawd3d_window_destroy(win_window_info *window);
static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window);
static void drawd3d_window_save(win_window_info *window);
static void drawd3d_window_record(win_window_info *window);
static void drawd3d_window_toggle_fsfx(win_window_info *window);
static int drawd3d_window_draw(win_window_info *window, HDC dc, int update);
//============================================================ //============================================================
// drawd3d_window_init // drawd3d_window_init
//============================================================ //============================================================
static int drawd3d_window_init(win_window_info *window) int d3d::renderer::init()
{ {
// allocate memory for our structures if (!initialize())
d3d::renderer *d3d = global_alloc(d3d::renderer(window));
window->m_drawdata = d3d;
if (!d3d->initialize())
{ {
drawd3d_window_destroy(window); destroy();
osd_printf_error("Unable to initialize Direct3D.\n"); osd_printf_error("Unable to initialize Direct3D.\n");
return 1; return 1;
} }
@ -218,22 +206,19 @@ static void drawd3d_exit(void)
(*d3dintf->d3d.release)(d3dintf); (*d3dintf->d3d.release)(d3dintf);
} }
static void drawd3d_window_toggle_fsfx(win_window_info *window) void d3d::renderer::toggle_fsfx()
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata; set_restarting(true);
d3d->set_restarting(true);
} }
static void drawd3d_window_record(win_window_info *window) void d3d::renderer::record()
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata; get_shaders()->window_record();
d3d->get_shaders()->window_record();
} }
static void drawd3d_window_save(win_window_info *window) void d3d::renderer::save()
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata; get_shaders()->window_save();
d3d->get_shaders()->window_save();
} }
@ -242,20 +227,11 @@ static void drawd3d_window_save(win_window_info *window)
// drawd3d_window_destroy // drawd3d_window_destroy
//============================================================ //============================================================
static void drawd3d_window_destroy(win_window_info *window) void d3d::renderer::destroy()
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata; if (get_shaders() != NULL && get_shaders()->recording())
get_shaders()->window_record();
// skip if nothing
if (d3d == NULL)
return;
if (d3d->get_shaders() != NULL && d3d->get_shaders()->recording())
d3d->get_shaders()->window_record();
// free the memory in the window
global_free(d3d);
window->m_drawdata = NULL;
} }
@ -264,21 +240,29 @@ static void drawd3d_window_destroy(win_window_info *window)
// drawd3d_window_get_primitives // drawd3d_window_get_primitives
//============================================================ //============================================================
static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window) render_primitive_list *d3d::renderer::get_primitives()
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata;
RECT client; RECT client;
GetClientRectExceptMenu(window->m_hwnd, &client, window->m_fullscreen); GetClientRectExceptMenu(window().m_hwnd, &client, window().m_fullscreen);
if (rect_width(&client) > 0 && rect_height(&client) > 0) if (rect_width(&client) > 0 && rect_height(&client) > 0)
{ {
window->m_target->set_bounds(rect_width(&client), rect_height(&client), window->m_monitor->get_aspect()); window().m_target->set_bounds(rect_width(&client), rect_height(&client), window().m_monitor->get_aspect());
window->m_target->set_max_update_rate((d3d->get_refresh() == 0) ? d3d->get_origmode().RefreshRate : d3d->get_refresh()); window().m_target->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
} }
return &window->m_target->get_primitives(); return &window().m_target->get_primitives();
} }
int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks) //============================================================
// drawnone_create
//============================================================
static osd_renderer *drawd3d_create(win_window_info *window)
{
return global_alloc(d3d::renderer(window));
}
int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks)
{ {
d3dintf = NULL; d3dintf = NULL;
@ -295,13 +279,7 @@ int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks)
// fill in the callbacks // fill in the callbacks
memset(callbacks, 0, sizeof(*callbacks)); memset(callbacks, 0, sizeof(*callbacks));
callbacks->exit = drawd3d_exit; callbacks->exit = drawd3d_exit;
callbacks->window_init = drawd3d_window_init; callbacks->create = drawd3d_create;
callbacks->window_get_primitives = drawd3d_window_get_primitives;
callbacks->window_draw = drawd3d_window_draw;
callbacks->window_save = drawd3d_window_save;
callbacks->window_record = drawd3d_window_record;
callbacks->window_toggle_fsfx = drawd3d_window_toggle_fsfx;
callbacks->window_destroy = drawd3d_window_destroy;
return 0; return 0;
} }
@ -309,21 +287,15 @@ int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks)
// drawd3d_window_draw // drawd3d_window_draw
//============================================================ //============================================================
static int drawd3d_window_draw(win_window_info *window, HDC dc, int update) int d3d::renderer::draw(HDC dc, int update)
{ {
d3d::renderer *d3d = (d3d::renderer *)window->m_drawdata; int check = pre_window_draw_check();
// if we haven't been created, just punt
if (d3d == NULL)
return 1;
int check = d3d->pre_window_draw_check();
if (check >= 0) if (check >= 0)
return check; return check;
d3d->begin_frame(); begin_frame();
d3d->process_primitives(); process_primitives();
d3d->end_frame(); end_frame();
return 0; return 0;
} }
@ -496,7 +468,7 @@ texture_manager::texture_manager(renderer *d3d)
osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB"); osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
// set the max texture size // set the max texture size
d3d->get_window()->m_target->set_max_texture_size(m_texture_max_width, m_texture_max_height); d3d->window().m_target->set_max_texture_size(m_texture_max_width, m_texture_max_height);
osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height); osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
} }
@ -508,7 +480,7 @@ void texture_manager::create_resources()
{ {
// experimental: load a PNG to use for vector rendering; it is treated // experimental: load a PNG to use for vector rendering; it is treated
// as a brightness map // as a brightness map
emu_file file(m_renderer->get_window()->machine().options().art_path(), OPEN_FLAG_READ); emu_file file(m_renderer->window().machine().options().art_path(), OPEN_FLAG_READ);
render_load_png(m_vector_bitmap, file, NULL, "vector.png"); render_load_png(m_vector_bitmap, file, NULL, "vector.png");
if (m_vector_bitmap.valid()) if (m_vector_bitmap.valid())
{ {
@ -650,10 +622,10 @@ texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT3
} }
renderer::renderer(win_window_info *window) renderer::renderer(win_window_info *window)
: osd_renderer(window, FLAG_NONE)
{ {
m_device = NULL; m_device = NULL;
m_restarting = false; m_restarting = false;
m_window = window;
m_shaders = NULL; m_shaders = NULL;
m_numverts = 0; m_numverts = 0;
m_numpolys = 0; m_numpolys = 0;
@ -672,7 +644,7 @@ int renderer::initialize()
return false; return false;
// create the device immediately for the full screen case (defer for window mode) // create the device immediately for the full screen case (defer for window mode)
if (m_window->m_fullscreen && device_create()) if (window().m_fullscreen && device_create())
return false; return false;
return true; return true;
@ -681,7 +653,7 @@ int renderer::initialize()
int renderer::pre_window_draw_check() int renderer::pre_window_draw_check()
{ {
// if we're in the middle of resizing, leave things alone // if we're in the middle of resizing, leave things alone
if (m_window->m_resize_state == RESIZE_STATE_RESIZING) if (window().m_resize_state == RESIZE_STATE_RESIZING)
return 0; return 0;
// if we're restarting the renderer, leave things alone // if we're restarting the renderer, leave things alone
@ -706,7 +678,7 @@ int renderer::pre_window_draw_check()
} }
// in window mode, we need to track the window size // in window mode, we need to track the window size
if (!m_window->m_fullscreen || m_device == NULL) if (!window().m_fullscreen || m_device == NULL)
{ {
// if the size changes, skip this update since the render target will be out of date // if the size changes, skip this update since the render target will be out of date
if (update_window_size()) if (update_window_size())
@ -722,7 +694,7 @@ int renderer::pre_window_draw_check()
void texture_manager::update_textures() void texture_manager::update_textures()
{ {
for (render_primitive *prim = m_renderer->get_window()->m_primlist->first(); prim != NULL; prim = prim->next()) for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != NULL; prim = prim->next())
{ {
if (prim->texture.base != NULL) if (prim->texture.base != NULL)
{ {
@ -759,7 +731,7 @@ void renderer::begin_frame()
m_shaders->begin_frame(); m_shaders->begin_frame();
m_window->m_primlist->acquire_lock(); window().m_primlist->acquire_lock();
// first update any textures // first update any textures
m_texture_manager->update_textures(); m_texture_manager->update_textures();
@ -780,7 +752,7 @@ mtlog_add("drawd3d_window_draw: begin_scene");
m_line_count = 0; m_line_count = 0;
// loop over primitives // loop over primitives
for (render_primitive *prim = m_window->m_primlist->first(); prim != NULL; prim = prim->next()) for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags)) if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags))
m_line_count++; m_line_count++;
} }
@ -788,7 +760,7 @@ mtlog_add("drawd3d_window_draw: begin_scene");
void renderer::process_primitives() void renderer::process_primitives()
{ {
// Rotating index for vector time offsets // Rotating index for vector time offsets
for (render_primitive *prim = m_window->m_primlist->first(); prim != NULL; prim = prim->next()) for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
{ {
switch (prim->type) switch (prim->type)
{ {
@ -818,7 +790,7 @@ void renderer::process_primitives()
void renderer::end_frame() void renderer::end_frame()
{ {
m_window->m_primlist->release_lock(); window().m_primlist->release_lock();
// flush any pending polygons // flush any pending polygons
primitive_flush_pending(); primitive_flush_pending();
@ -893,18 +865,18 @@ try_again:
m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1; m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE; m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD; m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_presentation.hDeviceWindow = m_window->m_hwnd; m_presentation.hDeviceWindow = window().m_hwnd;
m_presentation.Windowed = !m_window->m_fullscreen || win_has_menu(m_window); m_presentation.Windowed = !window().m_fullscreen || win_has_menu(&window());
m_presentation.EnableAutoDepthStencil = FALSE; m_presentation.EnableAutoDepthStencil = FALSE;
m_presentation.AutoDepthStencilFormat = D3DFMT_D16; m_presentation.AutoDepthStencilFormat = D3DFMT_D16;
m_presentation.Flags = 0; m_presentation.Flags = 0;
m_presentation.FullScreen_RefreshRateInHz = m_refresh; m_presentation.FullScreen_RefreshRateInHz = m_refresh;
m_presentation.PresentationInterval = ((video_config.triplebuf && m_window->m_fullscreen) || m_presentation.PresentationInterval = ((video_config.triplebuf && window().m_fullscreen) ||
video_config.waitvsync || video_config.syncrefresh) ? video_config.waitvsync || video_config.syncrefresh) ?
D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
// create the D3D device // create the D3D device
result = (*d3dintf->d3d.create_device)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_window->m_focus_hwnd, result = (*d3dintf->d3d.create_device)(d3dintf, m_adapter, D3DDEVTYPE_HAL, window().m_focus_hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device); D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
if (result != D3D_OK) if (result != D3D_OK)
{ {
@ -927,10 +899,10 @@ try_again:
osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height); osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height);
// set the gamma if we need to // set the gamma if we need to
if (m_window->m_fullscreen) if (window().m_fullscreen)
{ {
// only set the gamma if it's not 1.0f // only set the gamma if it's not 1.0f
windows_options &options = downcast<windows_options &>(m_window->machine().options()); windows_options &options = downcast<windows_options &>(window().machine().options());
float brightness = options.full_screen_brightness(); float brightness = options.full_screen_brightness();
float contrast = options.full_screen_contrast(); float contrast = options.full_screen_contrast();
float gamma = options.full_screen_gamma(); float gamma = options.full_screen_gamma();
@ -1092,7 +1064,7 @@ int renderer::device_verify_caps()
int retval = 0; int retval = 0;
m_shaders = global_alloc_clear(shaders); m_shaders = global_alloc_clear(shaders);
m_shaders->init(d3dintf, m_window); m_shaders->init(d3dintf, &window());
DWORD tempcaps; DWORD tempcaps;
HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps); HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
@ -1231,12 +1203,12 @@ int renderer::config_adapter_mode()
} }
// choose a resolution: window mode case // choose a resolution: window mode case
if (!m_window->m_fullscreen || !video_config.switchres || win_has_menu(m_window)) if (!window().m_fullscreen || !video_config.switchres || win_has_menu(&window()))
{ {
RECT client; RECT client;
// bounds are from the window client rect // bounds are from the window client rect
GetClientRectExceptMenu(m_window->m_hwnd, &client, m_window->m_fullscreen); GetClientRectExceptMenu(window().m_hwnd, &client, window().m_fullscreen);
m_width = client.right - client.left; m_width = client.right - client.left;
m_height = client.bottom - client.top; m_height = client.bottom - client.top;
@ -1247,7 +1219,7 @@ int renderer::config_adapter_mode()
// make sure it's a pixel format we can get behind // make sure it's a pixel format we can get behind
if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8) if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8)
{ {
char *utf8_device = utf8_from_tstring(m_window->m_monitor->info.szDevice); char *utf8_device = utf8_from_tstring(window().m_monitor->info.szDevice);
if (utf8_device != NULL) if (utf8_device != NULL)
{ {
osd_printf_error("Device %s currently in an unsupported mode\n", utf8_device); osd_printf_error("Device %s currently in an unsupported mode\n", utf8_device);
@ -1272,10 +1244,10 @@ int renderer::config_adapter_mode()
} }
// see if we can handle the device type // see if we can handle the device type
result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !m_window->m_fullscreen); result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().m_fullscreen);
if (result != D3D_OK) if (result != D3D_OK)
{ {
char *utf8_device = utf8_from_tstring(m_window->m_monitor->info.szDevice); char *utf8_device = utf8_from_tstring(window().m_monitor->info.szDevice);
if (utf8_device != NULL) if (utf8_device != NULL)
{ {
osd_printf_error("Proposed video mode not supported on device %s\n", utf8_device); osd_printf_error("Proposed video mode not supported on device %s\n", utf8_device);
@ -1303,7 +1275,7 @@ int renderer::get_adapter_for_monitor()
HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum); HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum);
// if we match the proposed monitor, this is it // if we match the proposed monitor, this is it
if (curmonitor == m_window->m_monitor->handle) if (curmonitor == window().m_monitor->handle)
{ {
return adapternum; return adapternum;
} }
@ -1326,7 +1298,7 @@ void renderer::pick_best_mode()
float best_score = 0.0f; float best_score = 0.0f;
// determine the refresh rate of the primary screen // determine the refresh rate of the primary screen
const screen_device *primary_screen = m_window->machine().config().first_screen(); const screen_device *primary_screen = window().machine().config().first_screen();
if (primary_screen != NULL) if (primary_screen != NULL)
{ {
target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds()); target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
@ -1336,7 +1308,7 @@ void renderer::pick_best_mode()
// note: technically we should not be calling this from an alternate 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 // 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 // the main thread is waiting for us to finish, so it is safe to do so here
m_window->m_target->compute_minimum_size(minwidth, minheight); window().m_target->compute_minimum_size(minwidth, minheight);
// use those as the target for now // use those as the target for now
INT32 target_width = minwidth; INT32 target_width = minwidth;
@ -1371,7 +1343,7 @@ void renderer::pick_best_mode()
size_score *= 0.1f; size_score *= 0.1f;
// if we're looking for a particular mode, that's a winner // if we're looking for a particular mode, that's a winner
if (mode.Width == m_window->m_maxwidth && mode.Height == m_window->m_maxheight) if (mode.Width == window().m_maxwidth && mode.Height == window().m_maxheight)
size_score = 2.0f; size_score = 2.0f;
// compute refresh score // compute refresh score
@ -1382,7 +1354,7 @@ void renderer::pick_best_mode()
refresh_score *= 0.1f; refresh_score *= 0.1f;
// if we're looking for a particular refresh, make sure it matches // if we're looking for a particular refresh, make sure it matches
if (mode.RefreshRate == m_window->m_refresh) if (mode.RefreshRate == window().m_refresh)
refresh_score = 2.0f; refresh_score = 2.0f;
// weight size and refresh equally // weight size and refresh equally
@ -1412,19 +1384,19 @@ int renderer::update_window_size()
{ {
// get the current window bounds // get the current window bounds
RECT client; RECT client;
GetClientRectExceptMenu(m_window->m_hwnd, &client, m_window->m_fullscreen); GetClientRectExceptMenu(window().m_hwnd, &client, window().m_fullscreen);
// if we have a device and matching width/height, nothing to do // if we have a device and matching width/height, nothing to do
if (m_device != NULL && rect_width(&client) == m_width && rect_height(&client) == m_height) if (m_device != NULL && rect_width(&client) == m_width && rect_height(&client) == m_height)
{ {
// clear out any pending resizing if the area didn't change // clear out any pending resizing if the area didn't change
if (m_window->m_resize_state == RESIZE_STATE_PENDING) if (window().m_resize_state == RESIZE_STATE_PENDING)
m_window->m_resize_state = RESIZE_STATE_NORMAL; window().m_resize_state = RESIZE_STATE_NORMAL;
return FALSE; return FALSE;
} }
// if we're in the middle of resizing, leave it alone as well // if we're in the middle of resizing, leave it alone as well
if (m_window->m_resize_state == RESIZE_STATE_RESIZING) if (window().m_resize_state == RESIZE_STATE_RESIZING)
return FALSE; return FALSE;
// set the new bounds and create the device again // set the new bounds and create the device again
@ -1434,7 +1406,7 @@ int renderer::update_window_size()
return FALSE; return FALSE;
// reset the resize state to normal, and indicate we made a change // reset the resize state to normal, and indicate we made a change
m_window->m_resize_state = RESIZE_STATE_NORMAL; window().m_resize_state = RESIZE_STATE_NORMAL;
return TRUE; return TRUE;
} }
@ -1444,7 +1416,7 @@ int renderer::update_window_size()
void renderer::batch_vectors() void renderer::batch_vectors()
{ {
windows_options &options = downcast<windows_options &>(m_window->machine().options()); windows_options &options = downcast<windows_options &>(window().machine().options());
int vector_size = (options.antialias() ? 24 : 6); int vector_size = (options.antialias() ? 24 : 6);
m_vectorbatch = mesh_alloc(m_line_count * vector_size); m_vectorbatch = mesh_alloc(m_line_count * vector_size);
@ -1454,7 +1426,7 @@ void renderer::batch_vectors()
int line_index = 0; int line_index = 0;
float period = options.screen_vector_time_period(); float period = options.screen_vector_time_period();
UINT32 cached_flags = 0; UINT32 cached_flags = 0;
for (render_primitive *prim = m_window->m_primlist->first(); prim != NULL; prim = prim->next()) for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
{ {
switch (prim->type) switch (prim->type)
{ {

View File

@ -95,12 +95,20 @@ public:
}; };
/* renderer is the information about Direct3D for the current screen */ /* renderer is the information about Direct3D for the current screen */
class renderer class renderer : public osd_renderer
{ {
public: public:
renderer() { } //renderer() { }
renderer(win_window_info *window); renderer(win_window_info *window);
~renderer(); virtual ~renderer();
virtual int init();
virtual render_primitive_list *get_primitives();
virtual int draw(HDC dc, int update);
virtual void save();
virtual void record();
virtual void toggle_fsfx();
virtual void destroy();
int initialize(); int initialize();
@ -148,8 +156,6 @@ public:
int get_height() { return m_height; } int get_height() { return m_height; }
int get_refresh() { return m_refresh; } int get_refresh() { return m_refresh; }
win_window_info * get_window() { return m_window; }
device * get_device() { return m_device; } device * get_device() { return m_device; }
present_parameters * get_presentation() { return &m_presentation; } present_parameters * get_presentation() { return &m_presentation; }
@ -181,8 +187,6 @@ private:
int m_refresh; // current refresh rate int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors int m_create_error_count; // number of consecutive create errors
win_window_info * m_window; // current window info
device * m_device; // pointer to the Direct3DDevice object device * m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported? int m_gamma_supported; // is full screen gamma supported?
present_parameters m_presentation; // set of presentation parameters present_parameters m_presentation; // set of presentation parameters

File diff suppressed because it is too large Load Diff

View File

@ -18,47 +18,61 @@
#include "window.h" #include "window.h"
//============================================================ //============================================================
// TYPE DEFINITIONS // TYPE DEFINITIONS
//============================================================ //============================================================
/* gdi_info is the information for the current screen */ class renderer_gdi : public osd_renderer
struct gdi_info
{ {
public:
renderer_gdi(win_window_info *window)
: osd_renderer(window, FLAG_NONE), bmdata(NULL), bmsize(0) { }
virtual ~renderer_gdi() { }
virtual int init();
virtual render_primitive_list *get_primitives();
virtual int draw(HDC dc, int update);
virtual void save() {};
virtual void record() {};
virtual void toggle_fsfx() {};
virtual void destroy();
private:
/* gdi_info is the information for the current screen */
BITMAPINFO bminfo; BITMAPINFO bminfo;
UINT8 * bmdata; UINT8 * bmdata;
size_t bmsize; size_t bmsize;
}; };
//============================================================ //============================================================
// PROTOTYPES // PROTOTYPES
//============================================================ //============================================================
// core functions // core functions
static void drawgdi_exit(void); static void drawgdi_exit(void);
static int drawgdi_window_init(win_window_info *window);
static void drawgdi_window_destroy(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);
//============================================================
// drawnone_create
//============================================================
static osd_renderer *drawgdi_create(win_window_info *window)
{
return global_alloc(renderer_gdi(window));
}
//============================================================ //============================================================
// drawgdi_init // drawgdi_init
//============================================================ //============================================================
int drawgdi_init(running_machine &machine, win_draw_callbacks *callbacks) int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks)
{ {
// fill in the callbacks // fill in the callbacks
memset(callbacks, 0, sizeof(*callbacks)); memset(callbacks, 0, sizeof(*callbacks));
callbacks->exit = drawgdi_exit; callbacks->exit = drawgdi_exit;
callbacks->window_init = drawgdi_window_init; callbacks->create = drawgdi_create;
callbacks->window_get_primitives = drawgdi_window_get_primitives;
callbacks->window_draw = drawgdi_window_draw;
callbacks->window_destroy = drawgdi_window_destroy;
return 0; return 0;
} }
@ -78,22 +92,19 @@ static void drawgdi_exit(void)
// drawgdi_window_init // drawgdi_window_init
//============================================================ //============================================================
static int drawgdi_window_init(win_window_info *window) int renderer_gdi::init()
{ {
// allocate memory for our structures
gdi_info *gdi = global_alloc_clear(gdi_info);
window->m_drawdata = gdi;
// fill in the bitmap info header // fill in the bitmap info header
gdi->bminfo.bmiHeader.biSize = sizeof(gdi->bminfo.bmiHeader); bminfo.bmiHeader.biSize = sizeof(bminfo.bmiHeader);
gdi->bminfo.bmiHeader.biPlanes = 1; bminfo.bmiHeader.biPlanes = 1;
gdi->bminfo.bmiHeader.biBitCount = 32; bminfo.bmiHeader.biBitCount = 32;
gdi->bminfo.bmiHeader.biCompression = BI_RGB; bminfo.bmiHeader.biCompression = BI_RGB;
gdi->bminfo.bmiHeader.biSizeImage = 0; bminfo.bmiHeader.biSizeImage = 0;
gdi->bminfo.bmiHeader.biXPelsPerMeter = 0; bminfo.bmiHeader.biXPelsPerMeter = 0;
gdi->bminfo.bmiHeader.biYPelsPerMeter = 0; bminfo.bmiHeader.biYPelsPerMeter = 0;
gdi->bminfo.bmiHeader.biClrUsed = 0; bminfo.bmiHeader.biClrUsed = 0;
gdi->bminfo.bmiHeader.biClrImportant = 0; bminfo.bmiHeader.biClrImportant = 0;
return 0; return 0;
} }
@ -104,19 +115,12 @@ static int drawgdi_window_init(win_window_info *window)
// drawgdi_window_destroy // drawgdi_window_destroy
//============================================================ //============================================================
static void drawgdi_window_destroy(win_window_info *window) void renderer_gdi::destroy()
{ {
gdi_info *gdi = (gdi_info *)window->m_drawdata;
// skip if nothing
if (gdi == NULL)
return;
// free the bitmap memory // free the bitmap memory
if (gdi->bmdata != NULL) if (bmdata != NULL)
global_free_array(gdi->bmdata); global_free_array(bmdata);
global_free(gdi);
window->m_drawdata = NULL;
} }
@ -125,12 +129,12 @@ static void drawgdi_window_destroy(win_window_info *window)
// drawgdi_window_get_primitives // drawgdi_window_get_primitives
//============================================================ //============================================================
static render_primitive_list *drawgdi_window_get_primitives(win_window_info *window) render_primitive_list *renderer_gdi::get_primitives()
{ {
RECT client; RECT client;
GetClientRect(window->m_hwnd, &client); GetClientRect(window().m_hwnd, &client);
window->m_target->set_bounds(rect_width(&client), rect_height(&client), window->m_monitor->get_aspect()); window().m_target->set_bounds(rect_width(&client), rect_height(&client), window().m_monitor->get_aspect());
return &window->m_target->get_primitives(); return &window().m_target->get_primitives();
} }
@ -139,18 +143,17 @@ static render_primitive_list *drawgdi_window_get_primitives(win_window_info *win
// drawgdi_window_draw // drawgdi_window_draw
//============================================================ //============================================================
static int drawgdi_window_draw(win_window_info *window, HDC dc, int update) int renderer_gdi::draw(HDC dc, int update)
{ {
gdi_info *gdi = (gdi_info *)window->m_drawdata;
int width, height, pitch; int width, height, pitch;
RECT bounds; RECT bounds;
// we don't have any special resize behaviors // we don't have any special resize behaviors
if (window->m_resize_state == RESIZE_STATE_PENDING) if (window().m_resize_state == RESIZE_STATE_PENDING)
window->m_resize_state = RESIZE_STATE_NORMAL; window().m_resize_state = RESIZE_STATE_NORMAL;
// get the target bounds // get the target bounds
GetClientRect(window->m_hwnd, &bounds); GetClientRect(window().m_hwnd, &bounds);
// compute width/height/pitch of target // compute width/height/pitch of target
width = rect_width(&bounds); width = rect_width(&bounds);
@ -158,25 +161,25 @@ static int drawgdi_window_draw(win_window_info *window, HDC dc, int update)
pitch = (width + 3) & ~3; pitch = (width + 3) & ~3;
// make sure our temporary bitmap is big enough // make sure our temporary bitmap is big enough
if (pitch * height * 4 > gdi->bmsize) if (pitch * height * 4 > bmsize)
{ {
gdi->bmsize = pitch * height * 4 * 2; bmsize = pitch * height * 4 * 2;
global_free_array(gdi->bmdata); global_free_array(bmdata);
gdi->bmdata = global_alloc_array(UINT8, gdi->bmsize); bmdata = global_alloc_array(UINT8, bmsize);
} }
// draw the primitives to the bitmap // draw the primitives to the bitmap
window->m_primlist->acquire_lock(); window().m_primlist->acquire_lock();
software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window->m_primlist, gdi->bmdata, width, height, pitch); software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, bmdata, width, height, pitch);
window->m_primlist->release_lock(); window().m_primlist->release_lock();
// fill in bitmap-specific info // fill in bitmap-specific info
gdi->bminfo.bmiHeader.biWidth = pitch; bminfo.bmiHeader.biWidth = pitch;
gdi->bminfo.bmiHeader.biHeight = -height; bminfo.bmiHeader.biHeight = -height;
// blit to the screen // blit to the screen
StretchDIBits(dc, 0, 0, width, height, StretchDIBits(dc, 0, 0, width, height,
0, 0, width, height, 0, 0, width, height,
gdi->bmdata, &gdi->bminfo, DIB_RGB_COLORS, SRCCOPY); bmdata, &bminfo, DIB_RGB_COLORS, SRCCOPY);
return 0; return 0;
} }

View File

@ -17,6 +17,24 @@
#include "window.h" #include "window.h"
class renderer_none : public osd_renderer
{
public:
renderer_none(win_window_info *window)
: osd_renderer(window, FLAG_NONE) { }
virtual ~renderer_none() { }
virtual int init();
virtual render_primitive_list *get_primitives();
virtual int draw(HDC dc, int update);
virtual void save() { };
virtual void record() { };
virtual void toggle_fsfx() { };
virtual void destroy();
private:
};
//============================================================ //============================================================
// PROTOTYPES // PROTOTYPES
@ -24,26 +42,26 @@
// core functions // core functions
static void drawnone_exit(void); static void drawnone_exit(void);
static int drawnone_window_init(win_window_info *window);
static void drawnone_window_destroy(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);
//============================================================
// drawnone_create
//============================================================
osd_renderer *drawnone_create(win_window_info *window)
{
return global_alloc(renderer_none(window));
}
//============================================================ //============================================================
// drawnone_init // drawnone_init
//============================================================ //============================================================
int drawnone_init(running_machine &machine, win_draw_callbacks *callbacks) int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks)
{ {
// fill in the callbacks // fill in the callbacks
memset(callbacks, 0, sizeof(*callbacks)); memset(callbacks, 0, sizeof(*callbacks));
callbacks->exit = drawnone_exit; callbacks->exit = drawnone_exit;
callbacks->window_init = drawnone_window_init; callbacks->create = drawnone_create;
callbacks->window_get_primitives = drawnone_window_get_primitives;
callbacks->window_draw = drawnone_window_draw;
callbacks->window_destroy = drawnone_window_destroy;
return 0; return 0;
} }
@ -63,7 +81,7 @@ static void drawnone_exit(void)
// drawnone_window_init // drawnone_window_init
//============================================================ //============================================================
static int drawnone_window_init(win_window_info *window) int renderer_none::init()
{ {
return 0; return 0;
} }
@ -74,7 +92,7 @@ static int drawnone_window_init(win_window_info *window)
// drawnone_window_destroy // drawnone_window_destroy
//============================================================ //============================================================
static void drawnone_window_destroy(win_window_info *window) void renderer_none::destroy()
{ {
} }
@ -84,12 +102,12 @@ static void drawnone_window_destroy(win_window_info *window)
// drawnone_window_get_primitives // drawnone_window_get_primitives
//============================================================ //============================================================
static render_primitive_list *drawnone_window_get_primitives(win_window_info *window) render_primitive_list *renderer_none::get_primitives()
{ {
RECT client; RECT client;
GetClientRect(window->m_hwnd, &client); GetClientRect(window().m_hwnd, &client);
window->m_target->set_bounds(rect_width(&client), rect_height(&client), window->m_monitor->get_aspect()); window().m_target->set_bounds(rect_width(&client), rect_height(&client), window().m_monitor->get_aspect());
return &window->m_target->get_primitives(); return &window().m_target->get_primitives();
} }
@ -98,7 +116,7 @@ static render_primitive_list *drawnone_window_get_primitives(win_window_info *wi
// drawnone_window_draw // drawnone_window_draw
//============================================================ //============================================================
static int drawnone_window_draw(win_window_info *window, HDC dc, int update) int renderer_none::draw(HDC dc, int update)
{ {
return 0; return 0;
} }

View File

@ -35,11 +35,11 @@
#include "config.h" #include "config.h"
#include "winutf8.h" #include "winutf8.h"
extern int drawnone_init(running_machine &machine, win_draw_callbacks *callbacks); extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks);
extern int drawgdi_init(running_machine &machine, win_draw_callbacks *callbacks); extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks);
extern int drawdd_init(running_machine &machine, win_draw_callbacks *callbacks); extern int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks);
extern int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks); extern int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks);
extern int drawbgfx_init(running_machine &machine, win_draw_callbacks *callbacks); extern int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
//============================================================ //============================================================
@ -107,7 +107,7 @@ static DWORD window_threadid;
static DWORD last_update_time; static DWORD last_update_time;
static win_draw_callbacks draw; static osd_draw_callbacks draw;
static HANDLE ui_pause_event; static HANDLE ui_pause_event;
static HANDLE window_thread_ready_event; static HANDLE window_thread_ready_event;
@ -320,7 +320,7 @@ win_window_info::win_window_info(running_machine &machine)
m_lastclicktime(0), m_lastclicktime(0),
m_lastclickx(0), m_lastclickx(0),
m_lastclicky(0), m_lastclicky(0),
m_drawdata(NULL), m_renderer(NULL),
m_machine(machine) m_machine(machine)
{ {
memset(m_title,0,sizeof(m_title)); memset(m_title,0,sizeof(m_title));
@ -504,9 +504,6 @@ void winwindow_dispatch_message(running_machine &machine, MSG *message)
void winwindow_take_snap(void) void winwindow_take_snap(void)
{ {
if (draw.window_record == NULL)
return;
win_window_info *window; win_window_info *window;
assert(GetCurrentThreadId() == main_threadid); assert(GetCurrentThreadId() == main_threadid);
@ -514,7 +511,7 @@ void winwindow_take_snap(void)
// iterate over windows and request a snap // iterate over windows and request a snap
for (window = win_window_list; window != NULL; window = window->m_next) for (window = win_window_list; window != NULL; window = window->m_next)
{ {
(*draw.window_save)(window); window->m_renderer->save();
} }
} }
@ -527,9 +524,6 @@ void winwindow_take_snap(void)
void winwindow_toggle_fsfx(void) void winwindow_toggle_fsfx(void)
{ {
if (draw.window_toggle_fsfx == NULL)
return;
win_window_info *window; win_window_info *window;
assert(GetCurrentThreadId() == main_threadid); assert(GetCurrentThreadId() == main_threadid);
@ -537,7 +531,7 @@ void winwindow_toggle_fsfx(void)
// iterate over windows and request a snap // iterate over windows and request a snap
for (window = win_window_list; window != NULL; window = window->m_next) for (window = win_window_list; window != NULL; window = window->m_next)
{ {
(*draw.window_toggle_fsfx)(window); window->m_renderer->toggle_fsfx();
} }
} }
@ -550,9 +544,6 @@ void winwindow_toggle_fsfx(void)
void winwindow_take_video(void) void winwindow_take_video(void)
{ {
if (draw.window_record == NULL)
return;
win_window_info *window; win_window_info *window;
assert(GetCurrentThreadId() == main_threadid); assert(GetCurrentThreadId() == main_threadid);
@ -560,7 +551,7 @@ void winwindow_take_video(void)
// iterate over windows and request a snap // iterate over windows and request a snap
for (window = win_window_list; window != NULL; window = window->m_next) for (window = win_window_list; window != NULL; window = window->m_next)
{ {
(*draw.window_record)(window); window->m_renderer->record();
} }
} }
@ -812,7 +803,7 @@ void win_window_info::update()
} }
// if we're visible and running and not in the middle of a resize, draw // if we're visible and running and not in the middle of a resize, draw
if (m_hwnd != NULL && m_target != NULL && m_drawdata != NULL) if (m_hwnd != NULL && m_target != NULL)
{ {
int got_lock = TRUE; int got_lock = TRUE;
@ -835,7 +826,7 @@ void win_window_info::update()
osd_lock_release(m_render_lock); osd_lock_release(m_render_lock);
// ensure the target bounds are up-to-date, and then get the primitives // ensure the target bounds are up-to-date, and then get the primitives
primlist = (*draw.window_get_primitives)(this); primlist = m_renderer->get_primitives();
// post a redraw request with the primitive list as a parameter // post a redraw request with the primitive list as a parameter
last_update_time = timeGetTime(); last_update_time = timeGetTime();
@ -1241,7 +1232,8 @@ static int complete_create(win_window_info *window)
if (!window->m_fullscreen || window->m_fullscreen_safe) if (!window->m_fullscreen || window->m_fullscreen_safe)
{ {
// finish off by trying to initialize DirectX; if we fail, ignore it // finish off by trying to initialize DirectX; if we fail, ignore it
if ((*draw.window_init)(window)) window->m_renderer = draw.create(window);
if (window->m_renderer->init())
return 1; return 1;
ShowWindow(window->m_hwnd, SW_SHOW); ShowWindow(window->m_hwnd, SW_SHOW);
} }
@ -1417,7 +1409,9 @@ LRESULT CALLBACK winwindow_video_window_proc(HWND wnd, UINT message, WPARAM wpar
// destroy: clean up all attached rendering bits and NULL out our hwnd // destroy: clean up all attached rendering bits and NULL out our hwnd
case WM_DESTROY: case WM_DESTROY:
(*draw.window_destroy)(window); window->m_renderer->destroy();
global_free(window->m_renderer);
window->m_renderer = NULL;
window->m_hwnd = NULL; window->m_hwnd = NULL;
return DefWindowProc(wnd, message, wparam, lparam); return DefWindowProc(wnd, message, wparam, lparam);
@ -1501,7 +1495,7 @@ static void draw_video_contents(win_window_info *window, HDC dc, int update)
// otherwise, render with our drawing system // otherwise, render with our drawing system
else else
{ {
(*draw.window_draw)(window, dc, update); window->m_renderer->draw(dc, update);
mtlog_add("draw_video_contents: drawing finished"); mtlog_add("draw_video_contents: drawing finished");
} }
} }
@ -1871,7 +1865,9 @@ static void set_fullscreen(win_window_info *window, int fullscreen)
window->m_fullscreen = fullscreen; window->m_fullscreen = fullscreen;
// kill off the drawers // kill off the drawers
(*draw.window_destroy)(window); window->m_renderer->destroy();
global_free(window->m_renderer);
window->m_renderer = NULL;
// hide ourself // hide ourself
ShowWindow(window->m_hwnd, SW_HIDE); ShowWindow(window->m_hwnd, SW_HIDE);
@ -1927,7 +1923,8 @@ static void set_fullscreen(win_window_info *window, int fullscreen)
{ {
if (video_config.mode != VIDEO_MODE_NONE) if (video_config.mode != VIDEO_MODE_NONE)
ShowWindow(window->m_hwnd, SW_SHOW); ShowWindow(window->m_hwnd, SW_SHOW);
if ((*draw.window_init)(window)) window->m_renderer = draw.create(window);
if (window->m_renderer->init())
exit(1); exit(1);
} }

View File

@ -32,6 +32,8 @@
// TYPE DEFINITIONS // TYPE DEFINITIONS
//============================================================ //============================================================
class osd_renderer;
class win_window_info class win_window_info
{ {
public: public:
@ -77,24 +79,50 @@ public:
int m_lastclicky; int m_lastclicky;
// drawing data // drawing data
void * m_drawdata; osd_renderer * m_renderer;
private: private:
running_machine & m_machine; running_machine & m_machine;
}; };
class osd_renderer
struct win_draw_callbacks
{ {
void (*exit)(void); public:
int (*window_init)(win_window_info *window); /* Generic flags */
render_primitive_list *(*window_get_primitives)(win_window_info *window); static const int FLAG_NONE = 0x0000;
int (*window_draw)(win_window_info *window, HDC dc, int update); static const int FLAG_NEEDS_OPENGL = 0x0001;
void (*window_save)(win_window_info *window);
void (*window_record)(win_window_info *window); /* SDL 1.2 flags */
void (*window_toggle_fsfx)(win_window_info *window); static const int FLAG_NEEDS_DOUBLEBUF = 0x0100;
void (*window_destroy)(win_window_info *window); static const int FLAG_NEEDS_ASYNCBLIT = 0x0200;
osd_renderer(win_window_info *window, const int flags)
: m_window(window), m_flags(flags) { }
virtual ~osd_renderer() { }
win_window_info &window() { return *m_window; }
int flags() const { return m_flags; }
bool check_flag(const int flag) { return ((m_flags & flag)) == flag; }
virtual int init() = 0;
virtual render_primitive_list *get_primitives() = 0;
virtual int draw(HDC dc, int update) = 0;
virtual void save() = 0;
virtual void record() = 0;
virtual void toggle_fsfx() = 0;
virtual void destroy() = 0;
private:
win_window_info *m_window;
int m_flags;
};
struct osd_draw_callbacks
{
osd_renderer *(*create)(win_window_info *window);
void (*exit)(void);
}; };