From 5f53680e03d4b64a159f4318d5e3b5d8aa85df78 Mon Sep 17 00:00:00 2001 From: Zsolt Vasvari Date: Fri, 7 Mar 2008 07:19:38 +0000 Subject: [PATCH] - Removes video_data from running_machine - Private state screen information now hangs off the public one, instead of the other way around - Combines video_global and video_private into a single structure --- src/emu/mame.c | 1 - src/emu/mame.h | 2 - src/emu/video.c | 560 ++++++++++++++++++++++++------------------------ src/emu/video.h | 1 + 4 files changed, 277 insertions(+), 287 deletions(-) diff --git a/src/emu/mame.c b/src/emu/mame.c index c00bdf5aabe..0ebbe7b4420 100644 --- a/src/emu/mame.c +++ b/src/emu/mame.c @@ -1485,7 +1485,6 @@ static void prepare_machine(running_machine *machine) /* reset the global MAME data and clear the other privates */ memset(machine->mame_data, 0, sizeof(*machine->mame_data)); - machine->video_data = NULL; machine->palette_data = NULL; machine->streams_data = NULL; diff --git a/src/emu/mame.h b/src/emu/mame.h index cd36a88487d..2d73e5f6c81 100644 --- a/src/emu/mame.h +++ b/src/emu/mame.h @@ -162,7 +162,6 @@ typedef void (*output_callback_func)(void *param, const char *format, va_list ar /* forward type declarations */ typedef struct _mame_private mame_private; -typedef struct _video_private video_private; typedef struct _palette_private palette_private; typedef struct _streams_private streams_private; typedef struct _devices_private devices_private; @@ -205,7 +204,6 @@ struct _running_machine /* internal core information */ mame_private * mame_data; /* internal data from mame.c */ - video_private * video_data; /* internal data from video.c */ palette_private * palette_data; /* internal data from palette.c */ streams_private * streams_data; /* internal data from streams.c */ devices_private * devices_data; /* internal data from devices.c */ diff --git a/src/emu/video.c b/src/emu/video.c index b1f957b61c4..4d30386afcc 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -45,13 +45,12 @@ TYPE DEFINITIONS ***************************************************************************/ -typedef struct _internal_screen_info internal_screen_info; -struct _internal_screen_info +typedef struct _internal_screen_state internal_screen_state; +struct _internal_screen_state { - /* pointers to screen configuration and state */ + /* basic information about this screen */ int scrnum; /* the screen index */ const device_config * device; /* pointer to screen device configuration */ - screen_state * state; /* pointer to visible state in Machine structure */ /* textures and bitmaps */ render_texture * texture[2]; /* 2x textures for the screen bitmap */ @@ -73,8 +72,8 @@ struct _internal_screen_info emu_timer * scanline_timer; /* scanline timer */ UINT64 frame_number; /* the current frame number */ - /* VBLANK callbacks */ - int vbl_cb_count; /* # of callbacks installed */ + /* screen specific VBLANK callbacks */ + int vbl_cb_count; vblank_state_changed_func vbl_cbs[MAX_VBL_CB]; /* the array of callbacks */ /* movie recording */ @@ -83,24 +82,6 @@ struct _internal_screen_info }; -struct _video_private -{ - /* per-screen information */ - internal_screen_info scrinfo[MAX_SCREENS]; /* per-screen information */ - - /* snapshot stuff */ - render_target * snap_target; /* screen shapshot target */ - bitmap_t * snap_bitmap; /* screen snapshot bitmap */ - - /* crosshair bits */ - bitmap_t * crosshair_bitmap[MAX_PLAYERS]; /* crosshair bitmap per player */ - render_texture * crosshair_texture[MAX_PLAYERS]; /* crosshair texture per player */ - UINT8 crosshair_animate; /* animation frame index */ - UINT8 crosshair_visible; /* crosshair visible mask */ - UINT8 crosshair_needed; /* crosshair needed mask */ -}; - - typedef struct _video_global video_global; struct _video_global { @@ -140,6 +121,17 @@ struct _video_global INT8 frameskip_adjust; UINT8 skipping_this_frame;/* flag: TRUE if we are skipping the current frame */ osd_ticks_t average_oversleep; /* average number of ticks the OSD oversleeps */ + + /* snapshot stuff */ + render_target * snap_target; /* screen shapshot target */ + bitmap_t * snap_bitmap; /* screen snapshot bitmap */ + + /* crosshair bits */ + bitmap_t * crosshair_bitmap[MAX_PLAYERS]; /* crosshair bitmap per player */ + render_texture * crosshair_texture[MAX_PLAYERS]; /* crosshair texture per player */ + UINT8 crosshair_animate; /* animation frame index */ + UINT8 crosshair_visible; /* crosshair visible mask */ + UINT8 crosshair_needed; /* crosshair needed mask */ }; @@ -177,6 +169,7 @@ static const UINT8 skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS] = /* core implementation */ static void video_exit(running_machine *machine); static void init_buffered_spriteram(void); +static internal_screen_state *get_internal_state(running_machine *machine, int scrnum); /* graphics decoding */ static void allocate_graphics(running_machine *machine, const gfx_decode_entry *gfxdecodeinfo); @@ -196,16 +189,16 @@ static void update_frameskip(void); static void recompute_speed(running_machine *machine, attotime emutime); /* screen snapshots */ -static bitmap_t *get_snapshot_bitmap(running_machine *machine, int scrnum); +static void create_snapshot_bitmap(running_machine *machine, int scrnum); static file_error mame_fopen_next(running_machine *machine, const char *pathoption, const char *extension, mame_file **file); /* movie recording */ static void movie_record_frame(running_machine *machine, int scrnum); /* crosshair rendering */ -static void crosshair_init(running_machine *machine, video_private *viddata); -static void crosshair_render(running_machine *machine, video_private *viddata); -static void crosshair_free(video_private *viddata); +static void crosshair_init(running_machine *machine); +static void crosshair_render(running_machine *machine); +static void crosshair_free(void); /* software rendering */ static void rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); @@ -216,6 +209,21 @@ static void rgb888_draw_primitives(const render_primitive *primlist, void *dstda INLINE FUNCTIONS ***************************************************************************/ +/*------------------------------------------------- + get_safe_token - makes sure that the passed + in device is, in fact, a screen +-------------------------------------------------*/ + +INLINE screen_state *get_safe_token(const device_config *device) +{ + assert(device != NULL); + assert(device->token != NULL); + assert(device->type == DEVICE_GET_INFO_NAME(video_screen)); + + return (screen_state *)device->token; +} + + /*------------------------------------------------- effective_autoframeskip - return the effective autoframeskip value, accounting for fast @@ -283,7 +291,6 @@ INLINE int effective_throttle(void) void video_init(running_machine *machine) { const device_config *device; - video_private *viddata; const char *filename; /* reset our global state */ @@ -300,10 +307,6 @@ void video_init(running_machine *machine) global.refresh_speed = options_get_bool(mame_options(), OPTION_REFRESHSPEED); global.update_in_pause = options_get_bool(mame_options(), OPTION_UPDATEINPAUSE); - /* allocate memory for our private data */ - viddata = machine->video_data = auto_malloc(sizeof(*viddata)); - memset(viddata, 0, sizeof(*viddata)); - /* request a callback upon exiting */ add_exit_callback(machine, video_exit); @@ -312,23 +315,29 @@ void video_init(running_machine *machine) { int scrnum = device_list_index(machine->config->devicelist, VIDEO_SCREEN, device->tag); render_container *container = render_container_get_screen(scrnum); - internal_screen_info *info = &viddata->scrinfo[scrnum]; screen_config *config = device->inline_config; + screen_state *state = &machine->screen[scrnum]; + + /* allocate the private state */ + internal_screen_state *internal_state = auto_malloc(sizeof(*internal_state)); + memset(internal_state, 0, sizeof(*internal_state)); /* allocate the VBLANK timers */ - info->vblank_begin_timer = timer_alloc(vblank_begin_callback, info); - info->vblank_end_timer = timer_alloc(vblank_end_callback, info); + internal_state->vblank_begin_timer = timer_alloc(vblank_begin_callback, state); + internal_state->vblank_end_timer = timer_alloc(vblank_end_callback, internal_state); /* allocate a timer to reset partial updates */ - info->scanline0_timer = timer_alloc(scanline0_callback, NULL); + internal_state->scanline0_timer = timer_alloc(scanline0_callback, internal_state); - /* make pointers back to the config and state */ - info->scrnum = scrnum; - info->device = device; - info->state = &machine->screen[scrnum]; + /* save some cross-reference information that makes our life easier */ + internal_state->scrnum = scrnum; + internal_state->device = device; + + /* hook up our private state structure */ + state->private_data = internal_state; /* configure the screen with the default parameters */ - video_screen_configure(scrnum, info->state->width, info->state->height, &info->state->visarea, info->state->refresh); + video_screen_configure(scrnum, state->width, state->height, &state->visarea, state->refresh); /* configure the default cliparea */ if (config->xoffset != 0) @@ -341,19 +350,19 @@ void video_init(running_machine *machine) render_container_set_yscale(container, config->yscale); /* reset VBLANK timing */ - info->vblank_time = attotime_zero; + internal_state->vblank_time = attotime_zero; /* allocate a timer to generate per-scanline updates */ if (machine->config->video_attributes & VIDEO_UPDATE_SCANLINE) { - info->scanline_timer = timer_alloc(scanline_update_callback, NULL); - timer_adjust_oneshot(info->scanline_timer, video_screen_get_time_until_pos(scrnum, 0, 0), scrnum); + internal_state->scanline_timer = timer_alloc(scanline_update_callback, state); + timer_adjust_oneshot(internal_state->scanline_timer, video_screen_get_time_until_pos(scrnum, 0, 0), scrnum); } /* register for save states */ - state_save_register_item("video", scrnum, info->vblank_time.seconds); - state_save_register_item("video", scrnum, info->vblank_time.attoseconds); - state_save_register_item("video", scrnum, info->frame_number); + state_save_register_item("video", scrnum, internal_state->vblank_time.seconds); + state_save_register_item("video", scrnum, internal_state->vblank_time.attoseconds); + state_save_register_item("video", scrnum, internal_state->frame_number); } /* create spriteram buffers if necessary */ @@ -379,17 +388,15 @@ void video_init(running_machine *machine) tilemap_init(machine); /* create a render target for snapshots */ - if (viddata->scrinfo[0].state != NULL) + if (machine->screen[0].private_data != NULL) { - viddata->snap_target = render_target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); - assert(viddata->snap_target != NULL); - if (viddata->snap_target == NULL) - fatalerror("Unable to allocate snapshot render target\n"); - render_target_set_layer_config(viddata->snap_target, 0); + global.snap_target = render_target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); + assert(global.snap_target != NULL); + render_target_set_layer_config(global.snap_target, 0); } /* create crosshairs */ - crosshair_init(machine, viddata); + crosshair_init(machine); /* start recording movie if specified */ filename = options_get_string(mame_options(), OPTION_MNGWRITE); @@ -404,12 +411,11 @@ void video_init(running_machine *machine) static void video_exit(running_machine *machine) { - video_private *viddata = machine->video_data; int scrnum; int i; /* free crosshairs */ - crosshair_free(viddata); + crosshair_free(); /* stop recording any movie */ video_movie_end_recording(machine, 0); @@ -421,7 +427,7 @@ static void video_exit(running_machine *machine) /* free all the textures and bitmaps */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) { - internal_screen_info *info = &viddata->scrinfo[scrnum]; + internal_screen_state *info = get_internal_state(machine, scrnum); if (info->texture[0] != NULL) render_texture_free(info->texture[0]); if (info->texture[1] != NULL) @@ -433,10 +439,10 @@ static void video_exit(running_machine *machine) } /* free the snapshot target */ - if (viddata->snap_target != NULL) - render_target_free(viddata->snap_target); - if (viddata->snap_bitmap != NULL) - bitmap_free(viddata->snap_bitmap); + if (global.snap_target != NULL) + render_target_free(global.snap_target); + if (global.snap_bitmap != NULL) + bitmap_free(global.snap_bitmap); /* print a final result if we have at least 5 seconds' worth of data */ if (global.overall_emutime.seconds >= 5) @@ -671,8 +677,8 @@ static void decode_graphics(running_machine *machine, const gfx_decode_entry *gf void video_screen_configure(int scrnum, int width, int height, const rectangle *visarea, attoseconds_t refresh) { const screen_config *scrconfig = device_list_find_by_index(Machine->config->devicelist, VIDEO_SCREEN, scrnum)->inline_config; - video_private *viddata = Machine->video_data; - internal_screen_info *info = &viddata->scrinfo[scrnum]; + screen_state *state = &Machine->screen[scrnum]; + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); /* reallocate bitmap if necessary */ if (scrconfig->type != SCREEN_TYPE_VECTOR) @@ -684,26 +690,26 @@ void video_screen_configure(int scrnum, int width, int height, const rectangle * fatalerror("video_screen_configure(): visible area must be contained within the width/height!"); /* extract the current width/height from the bitmap */ - if (info->bitmap[0] != NULL) + if (internal_state->bitmap[0] != NULL) { - curwidth = info->bitmap[0]->width; - curheight = info->bitmap[0]->height; + curwidth = internal_state->bitmap[0]->width; + curheight = internal_state->bitmap[0]->height; } /* if we're too small to contain this width/height, reallocate our bitmaps and textures */ if (width > curwidth || height > curheight) { - bitmap_format screen_format = info->state->format; + bitmap_format screen_format = state->format; /* free what we have currently */ - if (info->texture[0] != NULL) - render_texture_free(info->texture[0]); - if (info->texture[1] != NULL) - render_texture_free(info->texture[1]); - if (info->bitmap[0] != NULL) - bitmap_free(info->bitmap[0]); - if (info->bitmap[1] != NULL) - bitmap_free(info->bitmap[1]); + if (internal_state->texture[0] != NULL) + render_texture_free(internal_state->texture[0]); + if (internal_state->texture[1] != NULL) + render_texture_free(internal_state->texture[1]); + if (internal_state->bitmap[0] != NULL) + bitmap_free(internal_state->bitmap[0]); + if (internal_state->bitmap[1] != NULL) + bitmap_free(internal_state->bitmap[1]); /* compute new width/height */ curwidth = MAX(width, curwidth); @@ -713,35 +719,35 @@ void video_screen_configure(int scrnum, int width, int height, const rectangle * /* convert the screen format to a texture format */ switch (screen_format) { - case BITMAP_FORMAT_INDEXED16: info->format = TEXFORMAT_PALETTE16; break; - case BITMAP_FORMAT_RGB15: info->format = TEXFORMAT_RGB15; break; - case BITMAP_FORMAT_RGB32: info->format = TEXFORMAT_RGB32; break; + case BITMAP_FORMAT_INDEXED16: internal_state->format = TEXFORMAT_PALETTE16; break; + case BITMAP_FORMAT_RGB15: internal_state->format = TEXFORMAT_RGB15; break; + case BITMAP_FORMAT_RGB32: internal_state->format = TEXFORMAT_RGB32; break; default: fatalerror("Invalid bitmap format!"); break; } /* allocate bitmaps */ - info->bitmap[0] = bitmap_alloc(curwidth, curheight, screen_format); - bitmap_set_palette(info->bitmap[0], Machine->palette); - info->bitmap[1] = bitmap_alloc(curwidth, curheight, screen_format); - bitmap_set_palette(info->bitmap[1], Machine->palette); + internal_state->bitmap[0] = bitmap_alloc(curwidth, curheight, screen_format); + bitmap_set_palette(internal_state->bitmap[0], Machine->palette); + internal_state->bitmap[1] = bitmap_alloc(curwidth, curheight, screen_format); + bitmap_set_palette(internal_state->bitmap[1], Machine->palette); /* allocate textures */ - info->texture[0] = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(info->texture[0], info->bitmap[0], visarea, 0, info->format); - info->texture[1] = render_texture_alloc(NULL, NULL); - render_texture_set_bitmap(info->texture[1], info->bitmap[1], visarea, 0, info->format); + internal_state->texture[0] = render_texture_alloc(NULL, NULL); + render_texture_set_bitmap(internal_state->texture[0], internal_state->bitmap[0], visarea, 0, internal_state->format); + internal_state->texture[1] = render_texture_alloc(NULL, NULL); + render_texture_set_bitmap(internal_state->texture[1], internal_state->bitmap[1], visarea, 0, internal_state->format); } } /* now fill in the new parameters */ - info->state->width = width; - info->state->height = height; - info->state->visarea = *visarea; - info->state->refresh = refresh; + state->width = width; + state->height = height; + state->visarea = *visarea; + state->refresh = refresh; /* compute timing parameters */ - info->scantime = refresh / height; - info->pixeltime = refresh / (height * width); + internal_state->scantime = refresh / height; + internal_state->pixeltime = refresh / (height * width); /* adjust speed if necessary */ if (global.refresh_speed) @@ -762,12 +768,12 @@ void video_screen_configure(int scrnum, int width, int height, const rectangle * /* if we are on scanline 0 already, reset the update timer immediately */ /* otherwise, defer until the next scanline 0 */ if (video_screen_get_vpos(scrnum) == 0) - timer_adjust_oneshot(info->scanline0_timer, attotime_zero, scrnum); + timer_adjust_oneshot(internal_state->scanline0_timer, attotime_zero, scrnum); else - timer_adjust_oneshot(info->scanline0_timer, video_screen_get_time_until_pos(scrnum, 0, 0), scrnum); + timer_adjust_oneshot(internal_state->scanline0_timer, video_screen_get_time_until_pos(scrnum, 0, 0), scrnum); /* start the VBLANK timer */ - timer_adjust_oneshot(info->vblank_begin_timer, video_screen_get_time_until_vblank_start(scrnum), 0); + timer_adjust_oneshot(internal_state->vblank_begin_timer, video_screen_get_time_until_vblank_start(scrnum), 0); } @@ -802,15 +808,15 @@ int video_screen_exists(int scrnum) /*------------------------------------------------- - get_screen_info - accessor function to get - private data for a screen + get_internal_state - accessor function to get + private state for a screen -------------------------------------------------*/ -static internal_screen_info *get_screen_info(running_machine *machine, int scrnum) +static internal_screen_state *get_internal_state(running_machine *machine, int scrnum) { - video_private *viddata = machine->video_data; - assert_always(video_screen_exists(scrnum), "Invalid screen"); - return &viddata->scrinfo[scrnum]; + assert(machine != NULL); + assert(video_screen_exists(scrnum)); + return (internal_screen_state *)machine->screen[scrnum].private_data; } @@ -822,8 +828,9 @@ static internal_screen_info *get_screen_info(running_machine *machine, int scrnu void video_screen_update_partial(int scrnum, int scanline) { - internal_screen_info *info = get_screen_info(Machine, scrnum); - rectangle clip = info->state->visarea; + screen_state *state = &Machine->screen[scrnum]; + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); + rectangle clip = state->visarea; LOG_PARTIAL_UPDATES(("Partial: video_screen_update_partial(%d,%d): ", scrnum, scanline)); @@ -846,15 +853,15 @@ void video_screen_update_partial(int scrnum, int scanline) } /* skip if less than the lowest so far */ - if (scanline < info->last_partial_scan) + if (scanline < internal_state->last_partial_scan) { LOG_PARTIAL_UPDATES(("skipped because less than previous\n")); return; } /* set the start/end scanlines */ - if (info->last_partial_scan > clip.min_y) - clip.min_y = info->last_partial_scan; + if (internal_state->last_partial_scan > clip.min_y) + clip.min_y = internal_state->last_partial_scan; if (scanline < clip.max_y) clip.max_y = scanline; @@ -867,16 +874,16 @@ void video_screen_update_partial(int scrnum, int scanline) LOG_PARTIAL_UPDATES(("updating %d-%d\n", clip.min_y, clip.max_y)); if (Machine->config->video_update != NULL) - flags = (*Machine->config->video_update)(Machine, scrnum, info->bitmap[info->curbitmap], &clip); + flags = (*Machine->config->video_update)(Machine, scrnum, internal_state->bitmap[internal_state->curbitmap], &clip); global.partial_updates_this_frame++; profiler_mark(PROFILER_END); /* if we modified the bitmap, we have to commit */ - info->changed |= ~flags & UPDATE_HAS_NOT_CHANGED; + internal_state->changed |= ~flags & UPDATE_HAS_NOT_CHANGED; } /* remember where we left off */ - info->last_partial_scan = scanline + 1; + internal_state->last_partial_scan = scanline + 1; } @@ -888,7 +895,7 @@ void video_screen_update_partial(int scrnum, int scanline) void video_screen_update_now(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); + screen_state *state = &Machine->screen[scrnum]; int current_vpos = video_screen_get_vpos(scrnum); int current_hpos = video_screen_get_hpos(scrnum); @@ -900,7 +907,7 @@ void video_screen_update_now(int scrnum) we only update up to the previous scanline. This minimizes the number of pixels that might be drawn incorrectly until we support a pixel level granularity */ - if ((current_hpos < (info->state->width / 2)) && (current_vpos > 0)) + if ((current_hpos < (state->width / 2)) && (current_vpos > 0)) current_vpos = current_vpos - 1; video_screen_update_partial(scrnum, current_vpos); @@ -915,18 +922,19 @@ void video_screen_update_now(int scrnum) int video_screen_get_vpos(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); - attoseconds_t delta = attotime_to_attoseconds(attotime_sub(timer_get_time(), info->vblank_time)); + screen_state *state = &Machine->screen[scrnum]; + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); + attoseconds_t delta = attotime_to_attoseconds(attotime_sub(timer_get_time(), internal_state->vblank_time)); int vpos; /* round to the nearest pixel */ - delta += info->pixeltime / 2; + delta += internal_state->pixeltime / 2; /* compute the v position relative to the start of VBLANK */ - vpos = delta / info->scantime; + vpos = delta / internal_state->scantime; /* adjust for the fact that VBLANK starts at the bottom of the visible area */ - return (info->state->visarea.max_y + 1 + vpos) % info->state->height; + return (state->visarea.max_y + 1 + vpos) % state->height; } @@ -938,21 +946,21 @@ int video_screen_get_vpos(int scrnum) int video_screen_get_hpos(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); - attoseconds_t delta = attotime_to_attoseconds(attotime_sub(timer_get_time(), info->vblank_time)); + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); + attoseconds_t delta = attotime_to_attoseconds(attotime_sub(timer_get_time(), internal_state->vblank_time)); int vpos; /* round to the nearest pixel */ - delta += info->pixeltime / 2; + delta += internal_state->pixeltime / 2; /* compute the v position relative to the start of VBLANK */ - vpos = delta / info->scantime; + vpos = delta / internal_state->scantime; /* subtract that from the total time */ - delta -= vpos * info->scantime; + delta -= vpos * internal_state->scantime; /* return the pixel offset from the start of this scanline */ - return delta / info->pixeltime; + return delta / internal_state->pixeltime; } @@ -963,8 +971,8 @@ int video_screen_get_hpos(int scrnum) int video_screen_get_vblank(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); - return info->vblank_state; + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); + return internal_state->vblank_state; } @@ -975,9 +983,9 @@ int video_screen_get_vblank(int scrnum) int video_screen_get_hblank(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); + screen_state *state = &Machine->screen[scrnum]; int hpos = video_screen_get_hpos(scrnum); - return (hpos < info->state->visarea.min_x || hpos > info->state->visarea.max_x); + return (hpos < state->visarea.min_x || hpos > state->visarea.max_x); } @@ -989,22 +997,23 @@ int video_screen_get_hblank(int scrnum) attotime video_screen_get_time_until_pos(int scrnum, int vpos, int hpos) { - internal_screen_info *info = get_screen_info(Machine, scrnum); - attoseconds_t curdelta = attotime_to_attoseconds(attotime_sub(timer_get_time(), info->vblank_time)); + screen_state *state = &Machine->screen[scrnum]; + internal_screen_state *internal_state = get_internal_state(Machine, scrnum); + attoseconds_t curdelta = attotime_to_attoseconds(attotime_sub(timer_get_time(), internal_state->vblank_time)); attoseconds_t targetdelta; /* since we measure time relative to VBLANK, compute the scanline offset from VBLANK */ - vpos += info->state->height - (info->state->visarea.max_y + 1); - vpos %= info->state->height; + vpos += state->height - (state->visarea.max_y + 1); + vpos %= state->height; /* compute the delta for the given X,Y position */ - targetdelta = (attoseconds_t)vpos * info->scantime + (attoseconds_t)hpos * info->pixeltime; + targetdelta = (attoseconds_t)vpos * internal_state->scantime + (attoseconds_t)hpos * internal_state->pixeltime; /* if we're past that time (within 1/2 of a pixel), head to the next frame */ - if (targetdelta <= curdelta + info->pixeltime / 2) - targetdelta += info->state->refresh; + if (targetdelta <= curdelta + internal_state->pixeltime / 2) + targetdelta += state->refresh; while (targetdelta <= curdelta) - targetdelta += info->state->refresh; + targetdelta += state->refresh; /* return the difference */ return attotime_make(0, targetdelta - curdelta); @@ -1059,7 +1068,7 @@ attotime video_screen_get_time_until_update(int scrnum) attotime video_screen_get_scan_period(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); + internal_screen_state *info = get_internal_state(Machine, scrnum); return attotime_make(0, info->scantime); } @@ -1084,27 +1093,25 @@ attotime video_screen_get_frame_period(int scrnum) UINT64 video_screen_get_frame_number(int scrnum) { - internal_screen_info *info = get_screen_info(Machine, scrnum); + internal_screen_state *info = get_internal_state(Machine, scrnum); return info->frame_number; } /*------------------------------------------------- video_screen_register_vbl_cb - registers a - VBLANK callback + VBLANK callback for a specific screen -------------------------------------------------*/ void video_screen_register_vbl_cb(running_machine *machine, void *screen, vblank_state_changed_func vbl_cb) { int i, found; - internal_screen_info *scrinfo = NULL; + internal_screen_state *internal_state = NULL; /* validate arguments */ assert(machine != NULL); assert(machine->config != NULL); assert(machine->config->devicelist != NULL); - assert(machine->video_data != NULL); - assert(machine->video_data->scrinfo != NULL); assert(vbl_cb != NULL); /* if the screen is NULL, grab the first screen -- we are installing a "global" handler */ @@ -1124,24 +1131,24 @@ void video_screen_register_vbl_cb(running_machine *machine, void *screen, vblank /* find the screen info structure for the given token - there should only be one */ for (i = 0; i < MAX_SCREENS; i++) - if (machine->video_data->scrinfo[i].state == screen) - scrinfo = machine->video_data->scrinfo + i; + if (machine->screen[i].private_data == ((screen_state *)screen)->private_data) + internal_state = get_internal_state(machine, i); /* make sure we still have room for the callback */ - assert(scrinfo != NULL); - assert(scrinfo->vbl_cb_count != MAX_VBL_CB); + assert(internal_state != NULL); + assert(internal_state->vbl_cb_count != MAX_VBL_CB); /* check if we already have this callback registered */ found = FALSE; - for (i = 0; i < scrinfo->vbl_cb_count; i++) - if (scrinfo->vbl_cbs[i] == vbl_cb) + for (i = 0; i < internal_state->vbl_cb_count; i++) + if (internal_state->vbl_cbs[i] == vbl_cb) found = TRUE; /* if not found, register and increment count */ if (!found) { - scrinfo->vbl_cbs[scrinfo->vbl_cb_count] = vbl_cb; - scrinfo->vbl_cb_count++; + internal_state->vbl_cbs[internal_state->vbl_cb_count] = vbl_cb; + internal_state->vbl_cb_count++; } } @@ -1216,14 +1223,14 @@ DEVICE_GET_INFO( video_screen ) callsbacks with the given state -------------------------------------------------*/ -static void call_vb_callbacks(internal_screen_info *scrinfo, int vblank_state) +static void call_vb_callbacks(internal_screen_state *scrinfo, int vblank_state) { int i; /* set it in the state structure */ scrinfo->vblank_state = vblank_state; - for (i = 0; i < scrinfo->vbl_cb_count; i++) + for (i = 0; scrinfo->vbl_cbs[i] != NULL; i++) scrinfo->vbl_cbs[i](scrinfo->device, vblank_state); } @@ -1236,28 +1243,29 @@ static void call_vb_callbacks(internal_screen_info *scrinfo, int vblank_state) static TIMER_CALLBACK( vblank_begin_callback ) { attoseconds_t vblank_period; - internal_screen_info *scrinfo = ptr; + screen_state *state = ptr; + internal_screen_state *internal_state = (internal_screen_state *)state->private_data; /* reset the starting VBLANK time */ - scrinfo->vblank_time = timer_get_time(); + internal_state->vblank_time = timer_get_time(); /* call the external callbacks */ - call_vb_callbacks(scrinfo, TRUE); + call_vb_callbacks(internal_state, TRUE); /* do we update the screen now? - only do it for the first screen */ - if (!(machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK) && (scrinfo->scrnum == 0)) + if (!(machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK) && (internal_state->scrnum == 0)) video_frame_update(machine, FALSE); /* if there has been no VBLANK time specified in the MACHINE_DRIVER, compute it now from the visible area, otherwise just used the supplied value */ - if ((scrinfo->state->vblank == 0) && !scrinfo->state->oldstyle_vblank_supplied) - vblank_period = (scrinfo->state->refresh / scrinfo->state->height) * (scrinfo->state->height - (scrinfo->state->visarea.max_y + 1 - scrinfo->state->visarea.min_y)); + if ((state->vblank == 0) && !state->oldstyle_vblank_supplied) + vblank_period = (state->refresh / state->height) * (state->height - (state->visarea.max_y + 1 - state->visarea.min_y)); else - vblank_period = scrinfo->state->vblank; + vblank_period = state->vblank; /* reset the timers */ - timer_adjust_oneshot(scrinfo->vblank_begin_timer, attotime_make(0, scrinfo->state->refresh), 0); - timer_adjust_oneshot(scrinfo->vblank_end_timer, attotime_make(0, vblank_period), 0); + timer_adjust_oneshot(internal_state->vblank_begin_timer, attotime_make(0, state->refresh), 0); + timer_adjust_oneshot(internal_state->vblank_end_timer, attotime_make(0, vblank_period), 0); } @@ -1268,17 +1276,17 @@ static TIMER_CALLBACK( vblank_begin_callback ) static TIMER_CALLBACK( vblank_end_callback ) { - internal_screen_info *scrinfo = ptr; + internal_screen_state *internal_state = ptr; /* update the first screen if we didn't before */ - if ((machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK) && (scrinfo->scrnum == 0)) + if ((machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK) && (internal_state->scrnum == 0)) video_frame_update(machine, FALSE); /* let any external parties know that the VBLANK is over */ - call_vb_callbacks(scrinfo, FALSE); + call_vb_callbacks(internal_state, FALSE); /* increment the frame number counter */ - scrinfo->frame_number++; + internal_state->frame_number++; } @@ -1289,14 +1297,13 @@ static TIMER_CALLBACK( vblank_end_callback ) static TIMER_CALLBACK( scanline0_callback ) { - video_private *viddata = machine->video_data; - int scrnum = param; + internal_screen_state *internal_state = ptr; /* reset partial updates */ - viddata->scrinfo[scrnum].last_partial_scan = 0; + internal_state->last_partial_scan = 0; global.partial_updates_this_frame = 0; - timer_adjust_oneshot(viddata->scrinfo[scrnum].scanline0_timer, video_screen_get_time_until_pos(scrnum, 0, 0), scrnum); + timer_adjust_oneshot(internal_state->scanline0_timer, video_screen_get_time_until_pos(internal_state->scrnum, 0, 0), 0); } @@ -1307,18 +1314,18 @@ static TIMER_CALLBACK( scanline0_callback ) static TIMER_CALLBACK( scanline_update_callback ) { - video_private *viddata = machine->video_data; - int scrnum = param & 0xff; - int scanline = param >> 8; + screen_state *state = ptr; + internal_screen_state *internal_state = (internal_screen_state *)state->private_data; + int scanline = param; /* force a partial update to the current scanline */ - video_screen_update_partial(scrnum, scanline); + video_screen_update_partial(internal_state->scrnum, scanline); /* compute the next visible scanline */ scanline++; - if (scanline > machine->screen[scrnum].visarea.max_y) - scanline = machine->screen[scrnum].visarea.min_y; - timer_adjust_oneshot(viddata->scrinfo[scrnum].scanline_timer, video_screen_get_time_until_pos(scrnum, scanline, 0), (scanline << 8) | scrnum); + if (scanline > state->visarea.max_y) + scanline = state->visarea.min_y; + timer_adjust_oneshot(internal_state->scanline_timer, video_screen_get_time_until_pos(internal_state->scrnum, scanline, 0), scanline); } @@ -1377,7 +1384,7 @@ void video_frame_update(running_machine *machine, int debug) { /* reset partial updates if we're paused or if the debugger is active */ if (video_screen_exists(0) && (mame_is_paused(machine) || debug || mame_debug_is_active())) - scanline0_callback(machine, NULL, 0); + scanline0_callback(machine, Machine->screen[0].private_data, 0); /* otherwise, call the video EOF callback */ else if (machine->config->video_eof != NULL) @@ -1397,7 +1404,6 @@ void video_frame_update(running_machine *machine, int debug) static int finish_screen_updates(running_machine *machine) { - video_private *viddata = machine->video_data; const device_config *device; int anything_changed = FALSE; int livemask; @@ -1414,7 +1420,7 @@ static int finish_screen_updates(running_machine *machine) for (device = video_screen_first(machine->config); device != NULL; device = video_screen_next(device)) { int scrnum = device_list_index(machine->config->devicelist, VIDEO_SCREEN, device->tag); - internal_screen_info *screen = &viddata->scrinfo[scrnum]; + internal_screen_state *internal_state = get_internal_state(machine, scrnum); /* only update if live */ if (livemask & (1 << scrnum)) @@ -1425,20 +1431,20 @@ static int finish_screen_updates(running_machine *machine) if (scrconfig->type != SCREEN_TYPE_VECTOR && (machine->config->video_attributes & VIDEO_SELF_RENDER) == 0) { /* if we're not skipping the frame and if the screen actually changed, then update the texture */ - if (!global.skipping_this_frame && screen->changed) + if (!global.skipping_this_frame && internal_state->changed) { - bitmap_t *bitmap = screen->bitmap[screen->curbitmap]; + bitmap_t *bitmap = internal_state->bitmap[internal_state->curbitmap]; rectangle fixedvis = machine->screen[scrnum].visarea; fixedvis.max_x++; fixedvis.max_y++; - render_texture_set_bitmap(screen->texture[screen->curbitmap], bitmap, &fixedvis, 0, screen->format); - screen->curtexture = screen->curbitmap; - screen->curbitmap = 1 - screen->curbitmap; + render_texture_set_bitmap(internal_state->texture[internal_state->curbitmap], bitmap, &fixedvis, 0, internal_state->format); + internal_state->curtexture = internal_state->curbitmap; + internal_state->curbitmap = 1 - internal_state->curbitmap; } /* create an empty container with a single quad */ render_container_empty(render_container_get_screen(scrnum)); - render_screen_add_quad(scrnum, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), screen->texture[screen->curtexture], PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); + render_screen_add_quad(scrnum, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), internal_state->texture[internal_state->curtexture], PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); } /* update our movie recording state */ @@ -1447,13 +1453,13 @@ static int finish_screen_updates(running_machine *machine) } /* reset the screen changed flags */ - if (screen->changed) + if (internal_state->changed) anything_changed = TRUE; - screen->changed = FALSE; + internal_state->changed = FALSE; } /* draw any crosshairs */ - crosshair_render(machine, viddata); + crosshair_render(machine); return anything_changed; } @@ -1974,14 +1980,11 @@ void video_screen_save_snapshot(running_machine *machine, mame_file *fp, int scr { const rgb_t *palette = (machine->palette != NULL) ? palette_entry_list_adjusted(machine->palette) : NULL; png_info pnginfo = { 0 }; - bitmap_t *bitmap; png_error error; char text[256]; - /* generate the bitmap to pass in */ - bitmap = get_snapshot_bitmap(machine, scrnum); - if (bitmap == NULL) - return; + /* create the bitmap to pass in */ + create_snapshot_bitmap(machine, scrnum); /* add two text entries describing the image */ sprintf(text, APPNAME " %s", build_version); @@ -1990,7 +1993,7 @@ void video_screen_save_snapshot(running_machine *machine, mame_file *fp, int scr png_add_text(&pnginfo, "System", text); /* now do the actual work */ - error = png_write_bitmap(mame_core_file(fp), &pnginfo, machine->video_data->snap_bitmap, machine->config->total_colors, palette); + error = png_write_bitmap(mame_core_file(fp), &pnginfo, global.snap_bitmap, machine->config->total_colors, palette); /* free any data allocated */ png_free(&pnginfo); @@ -2023,47 +2026,43 @@ void video_save_active_screen_snapshots(running_machine *machine) /*------------------------------------------------- - get_snapshot_bitmap - return a pointer to the + creare_snapshot_bitmap - creates a bitmap containing the screenshot for the given screen number -------------------------------------------------*/ -static bitmap_t *get_snapshot_bitmap(running_machine *machine, int scrnum) +static void create_snapshot_bitmap(running_machine *machine, int scrnum) { - video_private *viddata = machine->video_data; const render_primitive_list *primlist; INT32 width, height; assert(scrnum >= 0 && scrnum < MAX_SCREENS); - /* if no screens, do nothing */ - if (viddata->snap_target == NULL) - return NULL; - - /* select the appropriate view in our dummy target */ - render_target_set_view(viddata->snap_target, scrnum); - - /* get the minimum width/height and set it on the target */ - render_target_get_minimum_size(viddata->snap_target, &width, &height); - render_target_set_bounds(viddata->snap_target, width, height, 0); - - /* if we don't have a bitmap, or if it's not the right size, allocate a new one */ - if (viddata->snap_bitmap == NULL || width != viddata->snap_bitmap->width || height != viddata->snap_bitmap->height) + /* only do it, if there is at least one screen */ + if (global.snap_target != NULL) { - if (viddata->snap_bitmap != NULL) - bitmap_free(viddata->snap_bitmap); - viddata->snap_bitmap = bitmap_alloc(width, height, BITMAP_FORMAT_RGB32); - assert(viddata->snap_bitmap != NULL); + /* select the appropriate view in our dummy target */ + render_target_set_view(global.snap_target, scrnum); + + /* get the minimum width/height and set it on the target */ + render_target_get_minimum_size(global.snap_target, &width, &height); + render_target_set_bounds(global.snap_target, width, height, 0); + + /* 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) + { + if (global.snap_bitmap != NULL) + bitmap_free(global.snap_bitmap); + global.snap_bitmap = bitmap_alloc(width, height, BITMAP_FORMAT_RGB32); + assert(global.snap_bitmap != NULL); + } + + /* 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 the screen there */ - primlist = render_target_get_primitives(viddata->snap_target); - osd_lock_acquire(primlist->lock); - rgb888_draw_primitives(primlist->head, viddata->snap_bitmap->base, width, height, viddata->snap_bitmap->rowpixels); - osd_lock_release(primlist->lock); - - /* now do the actual work */ - return viddata->snap_bitmap; } @@ -2113,9 +2112,8 @@ static file_error mame_fopen_next(running_machine *machine, const char *pathopti int video_is_movie_active(running_machine *machine, int scrnum) { - video_private *viddata = machine->video_data; - internal_screen_info *info = &viddata->scrinfo[scrnum]; - return (info->movie_file != NULL); + internal_screen_state *internal_state = get_internal_state(machine, scrnum); + return (internal_state->movie_file != NULL); } @@ -2126,20 +2124,19 @@ int video_is_movie_active(running_machine *machine, int scrnum) void video_movie_begin_recording(running_machine *machine, int scrnum, const char *name) { - video_private *viddata = machine->video_data; - internal_screen_info *info = &viddata->scrinfo[scrnum]; + internal_screen_state *internal_state = get_internal_state(machine, scrnum); file_error filerr; /* close any existing movie file */ - if (info->movie_file != NULL) + if (internal_state->movie_file != NULL) video_movie_end_recording(machine, scrnum); /* create a new movie file and start recording */ if (name != NULL) - filerr = mame_fopen(SEARCHPATH_MOVIE, name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &info->movie_file); + filerr = mame_fopen(SEARCHPATH_MOVIE, name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &internal_state->movie_file); else - filerr = mame_fopen_next(machine, SEARCHPATH_MOVIE, "mng", &info->movie_file); - info->movie_frame = 0; + filerr = mame_fopen_next(machine, SEARCHPATH_MOVIE, "mng", &internal_state->movie_file); + internal_state->movie_frame = 0; } @@ -2150,16 +2147,15 @@ void video_movie_begin_recording(running_machine *machine, int scrnum, const cha void video_movie_end_recording(running_machine *machine, int scrnum) { - video_private *viddata = machine->video_data; - internal_screen_info *info = &viddata->scrinfo[scrnum]; + internal_screen_state *internal_state = get_internal_state(machine, scrnum); /* close the file if it exists */ - if (info->movie_file != NULL) + if (internal_state->movie_file != NULL) { - mng_capture_stop(mame_core_file(info->movie_file)); - mame_fclose(info->movie_file); - info->movie_file = NULL; - info->movie_frame = 0; + mng_capture_stop(mame_core_file(internal_state->movie_file)); + mame_fclose(internal_state->movie_file); + internal_state->movie_file = NULL; + internal_state->movie_frame = 0; } } @@ -2171,26 +2167,23 @@ void video_movie_end_recording(running_machine *machine, int scrnum) static void movie_record_frame(running_machine *machine, int scrnum) { - video_private *viddata = machine->video_data; - internal_screen_info *info = &viddata->scrinfo[scrnum]; + screen_state *state = &machine->screen[scrnum]; + internal_screen_state *internal_state = get_internal_state(machine, scrnum); const rgb_t *palette; /* only record if we have a file */ - if (info->movie_file != NULL) + if (internal_state->movie_file != NULL) { png_info pnginfo = { 0 }; - bitmap_t *bitmap; png_error error; profiler_mark(PROFILER_MOVIE_REC); - /* get the bitmap */ - bitmap = get_snapshot_bitmap(machine, scrnum); - if (bitmap == NULL) - return; + /* create the bitmap */ + create_snapshot_bitmap(machine, scrnum); /* track frames */ - if (info->movie_frame++ == 0) + if (internal_state->movie_frame++ == 0) { char text[256]; @@ -2201,7 +2194,7 @@ static void movie_record_frame(running_machine *machine, int scrnum) png_add_text(&pnginfo, "System", text); /* start the capture */ - error = mng_capture_start(mame_core_file(info->movie_file), bitmap, ATTOSECONDS_TO_HZ(viddata->scrinfo[scrnum].state->refresh)); + error = mng_capture_start(mame_core_file(internal_state->movie_file), global.snap_bitmap, ATTOSECONDS_TO_HZ(state->refresh)); if (error != PNGERR_NONE) { png_free(&pnginfo); @@ -2212,7 +2205,7 @@ static void movie_record_frame(running_machine *machine, int scrnum) /* write the next frame */ palette = (machine->palette != NULL) ? palette_entry_list_adjusted(machine->palette) : NULL; - error = mng_capture_frame(mame_core_file(info->movie_file), &pnginfo, bitmap, machine->config->total_colors, palette); + error = mng_capture_frame(mame_core_file(internal_state->movie_file), &pnginfo, global.snap_bitmap, machine->config->total_colors, palette); png_free(&pnginfo); if (error != PNGERR_NONE) { @@ -2307,46 +2300,46 @@ static const rgb_t crosshair_colors[] = bitmaps and such -------------------------------------------------*/ -static void crosshair_init(running_machine *machine, video_private *viddata) +static void crosshair_init(running_machine *machine) { input_port_entry *ipt; int player; /* determine who needs crosshairs */ - viddata->crosshair_needed = 0x00; + global.crosshair_needed = 0x00; for (ipt = machine->input_ports; ipt->type != IPT_END; ipt++) if (ipt->analog.crossaxis != CROSSHAIR_AXIS_NONE) - viddata->crosshair_needed |= 1 << ipt->player; + global.crosshair_needed |= 1 << ipt->player; /* all visible by default */ - viddata->crosshair_visible = viddata->crosshair_needed; + global.crosshair_visible = global.crosshair_needed; /* loop over each player and load or create a bitmap */ for (player = 0; player < MAX_PLAYERS; player++) - if (viddata->crosshair_needed & (1 << player)) + if (global.crosshair_needed & (1 << player)) { char filename[20]; /* first try to load a bitmap for the crosshair */ sprintf(filename, "cross%d.png", player); - viddata->crosshair_bitmap[player] = render_load_png(NULL, filename, NULL, NULL); + global.crosshair_bitmap[player] = render_load_png(NULL, filename, NULL, NULL); /* if that didn't work, make one up */ - if (viddata->crosshair_bitmap[player] == NULL) + if (global.crosshair_bitmap[player] == NULL) { rgb_t color = crosshair_colors[player]; int x, y; /* allocate a blank bitmap to start with */ - viddata->crosshair_bitmap[player] = bitmap_alloc(CROSSHAIR_RAW_SIZE, CROSSHAIR_RAW_SIZE, BITMAP_FORMAT_ARGB32); - fillbitmap(viddata->crosshair_bitmap[player], MAKE_ARGB(0x00,0xff,0xff,0xff), NULL); + global.crosshair_bitmap[player] = bitmap_alloc(CROSSHAIR_RAW_SIZE, CROSSHAIR_RAW_SIZE, BITMAP_FORMAT_ARGB32); + fillbitmap(global.crosshair_bitmap[player], MAKE_ARGB(0x00,0xff,0xff,0xff), NULL); /* extract the raw source data to it */ for (y = 0; y < CROSSHAIR_RAW_SIZE / 2; y++) { /* assume it is mirrored vertically */ - UINT32 *dest0 = BITMAP_ADDR32(viddata->crosshair_bitmap[player], y, 0); - UINT32 *dest1 = BITMAP_ADDR32(viddata->crosshair_bitmap[player], CROSSHAIR_RAW_SIZE - 1 - y, 0); + UINT32 *dest0 = BITMAP_ADDR32(global.crosshair_bitmap[player], y, 0); + UINT32 *dest1 = BITMAP_ADDR32(global.crosshair_bitmap[player], CROSSHAIR_RAW_SIZE - 1 - y, 0); /* extract to two rows simultaneously */ for (x = 0; x < CROSSHAIR_RAW_SIZE; x++) @@ -2356,8 +2349,8 @@ static void crosshair_init(running_machine *machine, video_private *viddata) } /* create a texture to reference the bitmap */ - viddata->crosshair_texture[player] = render_texture_alloc(render_texture_hq_scale, NULL); - render_texture_set_bitmap(viddata->crosshair_texture[player], viddata->crosshair_bitmap[player], NULL, 0, TEXFORMAT_ARGB32); + global.crosshair_texture[player] = render_texture_alloc(render_texture_hq_scale, NULL); + render_texture_set_bitmap(global.crosshair_texture[player], global.crosshair_bitmap[player], NULL, 0, TEXFORMAT_ARGB32); } } @@ -2369,19 +2362,18 @@ static void crosshair_init(running_machine *machine, video_private *viddata) void video_crosshair_toggle(void) { - video_private *viddata = Machine->video_data; int player; /* if we're all visible, turn all off */ - if (viddata->crosshair_visible == viddata->crosshair_needed) - viddata->crosshair_visible = 0; + if (global.crosshair_visible == global.crosshair_needed) + global.crosshair_visible = 0; /* otherwise, turn on the first bit that isn't currently on and stop there */ else for (player = 0; player < MAX_PLAYERS; player++) - if ((viddata->crosshair_needed & (1 << player)) && !(viddata->crosshair_visible & (1 << player))) + if ((global.crosshair_needed & (1 << player)) && !(global.crosshair_visible & (1 << player))) { - viddata->crosshair_visible |= 1 << player; + global.crosshair_visible |= 1 << player; break; } } @@ -2393,9 +2385,9 @@ void video_crosshair_toggle(void) a player's should be displayed -------------------------------------------------*/ -static UINT32 get_crosshair_screen_mask(video_private *viddata, int player) +static UINT32 get_crosshair_screen_mask(int player) { - return (viddata->crosshair_visible & (1 << player)) ? 1 : 0; + return (global.crosshair_visible & (1 << player)) ? 1 : 0; } @@ -2403,7 +2395,7 @@ static UINT32 get_crosshair_screen_mask(video_private *viddata, int player) crosshair_render - render the crosshairs -------------------------------------------------*/ -static void crosshair_render(running_machine *machine, video_private *viddata) +static void crosshair_render(running_machine *machine) { float x[MAX_PLAYERS], y[MAX_PLAYERS]; input_port_entry *ipt; @@ -2412,17 +2404,17 @@ static void crosshair_render(running_machine *machine, video_private *viddata) UINT8 tscale; /* skip if not needed */ - if (viddata->crosshair_visible == 0) + if (global.crosshair_visible == 0) return; /* animate via crosshair_animate */ - viddata->crosshair_animate += 0x04; + global.crosshair_animate += 0x04; /* compute a color scaling factor from the current animation value */ - if (viddata->crosshair_animate < 0x80) - tscale = 0xa0 + (0x60 * ( viddata->crosshair_animate & 0x7f) / 0x80); + if (global.crosshair_animate < 0x80) + tscale = 0xa0 + (0x60 * ( global.crosshair_animate & 0x7f) / 0x80); else - tscale = 0xa0 + (0x60 * (~viddata->crosshair_animate & 0x7f) / 0x80); + tscale = 0xa0 + (0x60 * (~global.crosshair_animate & 0x7f) / 0x80); /* read all the lightgun values */ for (ipt = machine->input_ports; ipt->type != IPT_END; ipt++) @@ -2462,7 +2454,7 @@ static void crosshair_render(running_machine *machine, video_private *viddata) /* draw all crosshairs */ for (player = 0; player < MAX_PLAYERS; player++) { - UINT32 scrmask = get_crosshair_screen_mask(viddata, player); + UINT32 scrmask = get_crosshair_screen_mask(player); if (scrmask != 0) { int scrnum; @@ -2476,7 +2468,7 @@ static void crosshair_render(running_machine *machine, video_private *viddata) x[player] - 0.03f, y[player] - 0.04f, x[player] + 0.03f, y[player] + 0.04f, MAKE_ARGB(0xc0, tscale, tscale, tscale), - viddata->crosshair_texture[player], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + global.crosshair_texture[player], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } } @@ -2489,20 +2481,20 @@ static void crosshair_render(running_machine *machine, video_private *viddata) the crosshairs -------------------------------------------------*/ -static void crosshair_free(video_private *viddata) +static void crosshair_free(void) { int player; /* free bitmaps and textures for each player */ for (player = 0; player < MAX_PLAYERS; player++) { - if (viddata->crosshair_texture[player] != NULL) - render_texture_free(viddata->crosshair_texture[player]); - viddata->crosshair_texture[player] = NULL; + if (global.crosshair_texture[player] != NULL) + render_texture_free(global.crosshair_texture[player]); + global.crosshair_texture[player] = NULL; - if (viddata->crosshair_bitmap[player] != NULL) - bitmap_free(viddata->crosshair_bitmap[player]); - viddata->crosshair_bitmap[player] = NULL; + if (global.crosshair_bitmap[player] != NULL) + bitmap_free(global.crosshair_bitmap[player]); + global.crosshair_bitmap[player] = NULL; } } diff --git a/src/emu/video.h b/src/emu/video.h index 3e3eefb8366..490b2d06f0d 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -70,6 +70,7 @@ struct _screen_state attoseconds_t refresh; /* refresh period */ attoseconds_t vblank; /* duration of a VBLANK */ bitmap_format format; /* bitmap format */ + void * private_data; /* pointer to the private data structure */ };