static int allocate_graphics(const gfx_decode *gfxdecodeinfo) { int i; /* loop over all elements */ for (i = 0; i < MAX_GFX_ELEMENTS && gfxdecodeinfo[i].memory_region != -1; i++) { int region_length = 8 * memory_region_length(gfxdecodeinfo[i].memory_region); UINT32 extxoffs[MAX_ABS_GFX_SIZE], extyoffs[MAX_ABS_GFX_SIZE]; UINT32 *xoffset, *yoffset; gfx_layout glcopy; int j; /* make a copy of the layout */ glcopy = *gfxdecodeinfo[i].gfxlayout; if (glcopy.extxoffs) { memcpy(extxoffs, glcopy.extxoffs, glcopy.width * sizeof(extxoffs[0])); glcopy.extxoffs = extxoffs; } if (glcopy.extyoffs) { memcpy(extyoffs, glcopy.extyoffs, glcopy.height * sizeof(extyoffs[0])); glcopy.extyoffs = extyoffs; } /* if the character count is a region fraction, compute the effective total */ if (IS_FRAC(glcopy.total)) glcopy.total = region_length / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total); /* loop over all the planes, converting fractions */ for (j = 0; j < glcopy.planes; j++) { UINT32 value = glcopy.planeoffset[j]; if (IS_FRAC(value)) glcopy.planeoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } /* loop over all the X/Y offsets, converting fractions */ xoffset = glcopy.extxoffs ? extxoffs : glcopy.xoffset; for (j = 0; j < glcopy.width; j++) { UINT32 value = xoffset[j]; if (IS_FRAC(value)) xoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } yoffset = glcopy.extyoffs ? extyoffs : glcopy.yoffset; for (j = 0; j < glcopy.height; j++) { UINT32 value = yoffset[j]; if (IS_FRAC(value)) yoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } /* some games increment on partial tile boundaries; to handle this without reading */ /* past the end of the region, we may need to truncate the count */ /* an example is the games in metro.c */ if (glcopy.planeoffset[0] == GFX_RAW) { int base = gfxdecodeinfo[i].start; int end = region_length/8; while (glcopy.total > 0) { int elementbase = base + (glcopy.total - 1) * glcopy.charincrement / 8; int lastpixelbase = elementbase + glcopy.height * yoffset[0] / 8 - 1; if (lastpixelbase < end) break; glcopy.total--; } } /* allocate the graphics */ Machine->gfx[i] = allocgfx(&glcopy); /* if we have a remapped colortable, point our local colortable to it */ if (Machine->remapped_colortable) Machine->gfx[i]->colortable = &Machine->remapped_colortable[gfxdecodeinfo[i].color_codes_start]; Machine->gfx[i]->total_colors = gfxdecodeinfo[i].total_color_codes; } return 0; }
void device_gfx_interface::decode_gfx(const gfx_decode_entry *gfxdecodeinfo) { // skip if nothing to do if (gfxdecodeinfo == NULL) return; // local variables to hold mutable copies of gfx layout data gfx_layout glcopy; dynamic_array<UINT32> extxoffs(0); dynamic_array<UINT32> extyoffs(0); // loop over all elements for (int curgfx = 0; curgfx < MAX_GFX_ELEMENTS && gfxdecodeinfo[curgfx].gfxlayout != NULL; curgfx++) { const gfx_decode_entry &gfx = gfxdecodeinfo[curgfx]; // extract the scale factors and xormask UINT32 xscale = GFXENTRY_GETXSCALE(gfx.flags); UINT32 yscale = GFXENTRY_GETYSCALE(gfx.flags); UINT32 xormask = GFXENTRY_ISREVERSE(gfx.flags) ? 7 : 0; // resolve the region UINT32 region_length; const UINT8 *region_base; UINT8 region_width; endianness_t region_endianness; if (gfx.memory_region != NULL) { device_t &basedevice = (GFXENTRY_ISDEVICE(gfx.flags)) ? device() : *device().owner(); if (GFXENTRY_ISRAM(gfx.flags)) { memory_share *share = basedevice.memshare(gfx.memory_region); assert(share != NULL); region_length = 8 * share->bytes(); region_base = reinterpret_cast<UINT8 *>(share->ptr()); region_width = share->width() / 8; region_endianness = share->endianness(); } else { memory_region *region = basedevice.memregion(gfx.memory_region); assert(region != NULL); region_length = 8 * region->bytes(); region_base = region->base(); region_width = region->width(); region_endianness = region->endianness(); } } else { region_length = 0; region_base = NULL; region_width = 1; region_endianness = ENDIANNESS_NATIVE; } if (region_endianness != ENDIANNESS_NATIVE) { switch (region_width) { case 2: xormask |= 0x08; break; case 4: xormask |= 0x18; break; case 8: xormask |= 0x38; break; } } // copy the layout into our temporary variable memcpy(&glcopy, gfx.gfxlayout, sizeof(gfx_layout)); // if the character count is a region fraction, compute the effective total if (IS_FRAC(glcopy.total)) { assert(region_length != 0); glcopy.total = region_length / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total); } // for non-raw graphics, decode the X and Y offsets if (glcopy.planeoffset[0] != GFX_RAW) { // copy the X and Y offsets into our temporary arrays extxoffs.resize(glcopy.width * xscale); extyoffs.resize(glcopy.height * yscale); memcpy(&extxoffs[0], (glcopy.extxoffs != NULL) ? glcopy.extxoffs : glcopy.xoffset, glcopy.width * sizeof(UINT32)); memcpy(&extyoffs[0], (glcopy.extyoffs != NULL) ? glcopy.extyoffs : glcopy.yoffset, glcopy.height * sizeof(UINT32)); // always use the extended offsets here glcopy.extxoffs = extxoffs; glcopy.extyoffs = extyoffs; // expand X and Y by the scale factors if (xscale > 1) { glcopy.width *= xscale; for (int j = glcopy.width - 1; j >= 0; j--) extxoffs[j] = extxoffs[j / xscale]; } if (yscale > 1) { glcopy.height *= yscale; for (int j = glcopy.height - 1; j >= 0; j--) extyoffs[j] = extyoffs[j / yscale]; } // loop over all the planes, converting fractions for (int j = 0; j < glcopy.planes; j++) { UINT32 value1 = glcopy.planeoffset[j]; if (IS_FRAC(value1)) { assert(region_length != 0); glcopy.planeoffset[j] = FRAC_OFFSET(value1) + region_length * FRAC_NUM(value1) / FRAC_DEN(value1); } } // loop over all the X/Y offsets, converting fractions for (int j = 0; j < glcopy.width; j++) { UINT32 value2 = extxoffs[j]; if (IS_FRAC(value2)) { assert(region_length != 0); extxoffs[j] = FRAC_OFFSET(value2) + region_length * FRAC_NUM(value2) / FRAC_DEN(value2); } } for (int j = 0; j < glcopy.height; j++) { UINT32 value3 = extyoffs[j]; if (IS_FRAC(value3)) { assert(region_length != 0); extyoffs[j] = FRAC_OFFSET(value3) + region_length * FRAC_NUM(value3) / FRAC_DEN(value3); } } } // otherwise, just use the line modulo else { int base = gfx.start; int end = region_length/8; int linemod = glcopy.yoffset[0]; while (glcopy.total > 0) { int elementbase = base + (glcopy.total - 1) * glcopy.charincrement / 8; int lastpixelbase = elementbase + glcopy.height * linemod / 8 - 1; if (lastpixelbase < end) break; glcopy.total--; } } // allocate the graphics m_gfx[curgfx].reset(global_alloc(gfx_element(m_palette, glcopy, (region_base != NULL) ? region_base + gfx.start : NULL, xormask, gfx.total_color_codes, gfx.color_codes_start))); } m_decoded = true; }
static void allocate_graphics(const gfx_decode *gfxdecodeinfo) { int i; /* loop over all elements */ for (i = 0; i < MAX_GFX_ELEMENTS && gfxdecodeinfo[i].memory_region != -1; i++) { int region_length = 8 * memory_region_length(gfxdecodeinfo[i].memory_region); UINT32 extxoffs[MAX_ABS_GFX_SIZE], extyoffs[MAX_ABS_GFX_SIZE]; gfx_layout glcopy; int j; /* make a copy of the layout */ glcopy = *gfxdecodeinfo[i].gfxlayout; if (glcopy.extxoffs) { memcpy(extxoffs, glcopy.extxoffs, glcopy.width * sizeof(extxoffs[0])); glcopy.extxoffs = extxoffs; } if (glcopy.extyoffs) { memcpy(extyoffs, glcopy.extyoffs, glcopy.height * sizeof(extyoffs[0])); glcopy.extyoffs = extyoffs; } /* if the character count is a region fraction, compute the effective total */ if (IS_FRAC(glcopy.total)) glcopy.total = region_length / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total); /* for non-raw graphics, decode the X and Y offsets */ if (glcopy.planeoffset[0] != GFX_RAW) { UINT32 *xoffset = glcopy.extxoffs ? extxoffs : glcopy.xoffset; UINT32 *yoffset = glcopy.extyoffs ? extyoffs : glcopy.yoffset; /* loop over all the planes, converting fractions */ for (j = 0; j < glcopy.planes; j++) { UINT32 value = glcopy.planeoffset[j]; if (IS_FRAC(value)) glcopy.planeoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } /* loop over all the X/Y offsets, converting fractions */ for (j = 0; j < glcopy.width; j++) { UINT32 value = xoffset[j]; if (IS_FRAC(value)) xoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } for (j = 0; j < glcopy.height; j++) { UINT32 value = yoffset[j]; if (IS_FRAC(value)) yoffset[j] = FRAC_OFFSET(value) + region_length * FRAC_NUM(value) / FRAC_DEN(value); } } /* otherwise, just use yoffset[0] as the line modulo */ else { int base = gfxdecodeinfo[i].start; int end = region_length/8; while (glcopy.total > 0) { int elementbase = base + (glcopy.total - 1) * glcopy.charincrement / 8; int lastpixelbase = elementbase + glcopy.height * glcopy.yoffset[0] / 8 - 1; if (lastpixelbase < end) break; glcopy.total--; } } /* allocate the graphics */ Machine->gfx[i] = allocgfx(&glcopy); /* if we have a remapped colortable, point our local colortable to it */ if (Machine->remapped_colortable) Machine->gfx[i]->colortable = &Machine->remapped_colortable[gfxdecodeinfo[i].color_codes_start]; Machine->gfx[i]->total_colors = gfxdecodeinfo[i].total_color_codes; } }
static int vh_open(void) { int i; int width,height; for (i = 0;i < MAX_GFX_ELEMENTS;i++) Machine->gfx[i] = 0; Machine->uifont = 0; if (palette_start() != 0) { vh_close(); return 1; } /* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */ /* convert_color_prom() routine (in palette_init()) because it might need to check the */ /* Machine->gfx[] data */ if (drv->gfxdecodeinfo) { for (i = 0;i < MAX_GFX_ELEMENTS && drv->gfxdecodeinfo[i].memory_region != -1;i++) { int reglen = 8*memory_region_length(drv->gfxdecodeinfo[i].memory_region); struct GfxLayout glcopy; int j; memcpy(&glcopy,drv->gfxdecodeinfo[i].gfxlayout,sizeof(glcopy)); if (IS_FRAC(glcopy.total)) glcopy.total = reglen / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total); for (j = 0;j < MAX_GFX_PLANES;j++) { if (IS_FRAC(glcopy.planeoffset[j])) { glcopy.planeoffset[j] = FRAC_OFFSET(glcopy.planeoffset[j]) + reglen * FRAC_NUM(glcopy.planeoffset[j]) / FRAC_DEN(glcopy.planeoffset[j]); } } for (j = 0;j < MAX_GFX_SIZE;j++) { if (IS_FRAC(glcopy.xoffset[j])) { glcopy.xoffset[j] = FRAC_OFFSET(glcopy.xoffset[j]) + reglen * FRAC_NUM(glcopy.xoffset[j]) / FRAC_DEN(glcopy.xoffset[j]); } if (IS_FRAC(glcopy.yoffset[j])) { glcopy.yoffset[j] = FRAC_OFFSET(glcopy.yoffset[j]) + reglen * FRAC_NUM(glcopy.yoffset[j]) / FRAC_DEN(glcopy.yoffset[j]); } } if ((Machine->gfx[i] = decodegfx(memory_region(drv->gfxdecodeinfo[i].memory_region) + drv->gfxdecodeinfo[i].start, &glcopy)) == 0) { vh_close(); bailing = 1; printf("Out of memory decoding gfx\n"); return 1; } if (Machine->remapped_colortable) Machine->gfx[i]->colortable = &Machine->remapped_colortable[drv->gfxdecodeinfo[i].color_codes_start]; Machine->gfx[i]->total_colors = drv->gfxdecodeinfo[i].total_color_codes; } } width = drv->screen_width; height = drv->screen_height; if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) scale_vectorgames(options.vector_width,options.vector_height,&width,&height); Machine->scrbitmap = bitmap_alloc_depth(width,height,Machine->color_depth); if (!Machine->scrbitmap) { vh_close(); return 1; } if (!(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)) { width = drv->default_visible_area.max_x - drv->default_visible_area.min_x + 1; height = drv->default_visible_area.max_y - drv->default_visible_area.min_y + 1; } if (Machine->orientation & ORIENTATION_SWAP_XY) { int temp; temp = width; width = height; height = temp; } /* create the display bitmap, and allocate the palette */ if (osd_create_display(width,height,Machine->color_depth, drv->frames_per_second,drv->video_attributes,Machine->orientation)) { vh_close(); return 1; } set_visible_area( drv->default_visible_area.min_x, drv->default_visible_area.max_x, drv->default_visible_area.min_y, drv->default_visible_area.max_y); /* create spriteram buffers if necessary */ if (drv->video_attributes & VIDEO_BUFFERS_SPRITERAM) { if (spriteram_size!=0) { buffered_spriteram= (unsigned char *) malloc(spriteram_size); if (!buffered_spriteram) { vh_close(); return 1; } if (spriteram_2_size!=0) buffered_spriteram_2 = (unsigned char *) malloc(spriteram_2_size); if (spriteram_2_size && !buffered_spriteram_2) { vh_close(); return 1; } } else { logerror("vh_open(): Video buffers spriteram but spriteram_size is 0\n"); buffered_spriteram=NULL; buffered_spriteram_2=NULL; } } /* build our private user interface font */ /* This must be done AFTER osd_create_display() so the function knows the */ /* resolution we are running at and can pick a different font depending on it. */ /* It must be done BEFORE palette_init() because that will also initialize */ /* (through osd_allocate_colors()) the uifont colortable. */ if ((Machine->uifont = builduifont()) == 0) { vh_close(); return 1; } /* initialize the palette - must be done after osd_create_display() */ if (palette_init()) { vh_close(); return 1; } return 0; }