/*------------------------------------------------- * resample_argb_bitmap_average - resample a texture * by performing a true weighted average over * all contributing pixels * -------------------------------------------------*/ static void resample_argb_bitmap_average(RawBufferPointer dest, u32 drowpixels, u32 dwidth, u32 dheight, RawBufferPointer source, u32 srowpixels, u32 swidth, u32 sheight, render_color color, u32 dx, u32 dy) // u32 *dest, const u32 *source { u64 sumscale = (u64)dx * (u64)dy; u32 r; u32 g; u32 b; u32 a; u32 x; u32 y; /* precompute premultiplied R/G/B/A factors */ r = (u32)(color.r * color.a * 256.0f); g = (u32)(color.g * color.a * 256.0f); b = (u32)(color.b * color.a * 256.0f); a = (u32)(color.a * 256.0f); /* loop over the target vertically */ for (y = 0; y < dheight; y++) { UInt32 starty = y * dy; /* loop over the target horizontally */ for (x = 0; x < dwidth; x++) { u64 sumr = 0; u64 sumg = 0; u64 sumb = 0; u64 suma = 0; u32 startx = x * dx; u32 xchunk; u32 ychunk; u32 curx; u32 cury; u32 yremaining = dy; /* accumulate all source pixels that contribute to this pixel */ for (cury = starty; yremaining != 0; cury += ychunk) { u32 xremaining = dx; /* determine the Y contribution, clamping to the amount remaining */ ychunk = 0x1000 - (cury & 0xfff); if (ychunk > yremaining) { ychunk = yremaining; } yremaining -= ychunk; /* loop over all source pixels in the X direction */ for (curx = startx; xremaining != 0; curx += xchunk) { UInt32 factor; /* determine the X contribution, clamping to the amount remaining */ xchunk = 0x1000 - (curx & 0xfff); if (xchunk > xremaining) { xchunk = xremaining; } xremaining -= xchunk; /* total contribution = x * y */ factor = xchunk * ychunk; /* fetch the source pixel */ rgb_t pix = new rgb_t(source.get_uint32((int)((cury >> 12) * srowpixels + (curx >> 12)))); // source[(cury >> 12) * srowpixels + (curx >> 12)]; /* accumulate the RGBA values */ sumr += factor * pix.r(); sumg += factor * pix.g(); sumb += factor * pix.b(); suma += factor * pix.a(); } } /* apply scaling */ suma = (suma / sumscale) * a / 256; sumr = (sumr / sumscale) * r / 256; sumg = (sumg / sumscale) * g / 256; sumb = (sumb / sumscale) * b / 256; /* if we're translucent, add in the destination pixel contribution */ if (a < 256) { rgb_t dpix = new rgb_t(dest.get_uint32((int)(y * drowpixels + x))); //dest[y * drowpixels + x]; suma += dpix.a() * (256 - a); sumr += dpix.r() * (256 - a); sumg += dpix.g() * (256 - a); sumb += dpix.b() * (256 - a); } /* store the target pixel, dividing the RGBA values by the overall scale factor */ dest.set_uint32((int)(y * drowpixels + x), new rgb_t((byte)suma, (byte)sumr, (byte)sumg, (byte)sumb)); // dest[y * drowpixels + x] = new rgb_t((byte)suma, (byte)sumr, (byte)sumg, (byte)sumb); } } }
/*------------------------------------------------- * resample_argb_bitmap_bilinear - perform texture * sampling via a bilinear filter * -------------------------------------------------*/ static void resample_argb_bitmap_bilinear(RawBufferPointer dest, u32 drowpixels, u32 dwidth, u32 dheight, RawBufferPointer source, u32 srowpixels, u32 swidth, u32 sheight, render_color color, u32 dx, u32 dy) //u32 *dest, const u32 *source { u32 maxx = swidth << 12; u32 maxy = sheight << 12; u32 r; u32 g; u32 b; u32 a; u32 x; u32 y; /* precompute premultiplied R/G/B/A factors */ r = (u32)(color.r * color.a * 256.0f); g = (u32)(color.g * color.a * 256.0f); b = (u32)(color.b * color.a * 256.0f); a = (u32)(color.a * 256.0f); /* loop over the target vertically */ for (y = 0; y < dheight; y++) { u32 starty = y * dy; /* loop over the target horizontally */ for (x = 0; x < dwidth; x++) { u32 startx = x * dx; rgb_t pix0; rgb_t pix1; rgb_t pix2; rgb_t pix3; u32 sumr; u32 sumg; u32 sumb; u32 suma; u32 nextx; u32 nexty; u32 curx; u32 cury; u32 factor; /* adjust start to the center; note that this math will tend to produce */ /* negative results on the first pixel, which is why we clamp below */ curx = startx + dx / 2 - 0x800; cury = starty + dy / 2 - 0x800; /* compute the neighboring pixel */ nextx = curx + 0x1000; nexty = cury + 0x1000; /* fetch the four relevant pixels */ pix0 = pix1 = pix2 = pix3 = new rgb_t(0); if ((int)cury >= 0 && cury < maxy && (int)curx >= 0 && curx < maxx) { pix0 = new rgb_t(source.get_uint32((int)((cury >> 12) * srowpixels + (curx >> 12)))); // source[(cury >> 12) * srowpixels + (curx >> 12)]; } if ((int)cury >= 0 && cury < maxy && (int)nextx >= 0 && nextx < maxx) { pix1 = new rgb_t(source.get_uint32((int)((cury >> 12) * srowpixels + (nextx >> 12)))); // source[(cury >> 12) * srowpixels + (nextx >> 12)]; } if ((int)nexty >= 0 && nexty < maxy && (int)curx >= 0 && curx < maxx) { pix2 = new rgb_t(source.get_uint32((int)((nexty >> 12) * srowpixels + (curx >> 12)))); // source[(nexty >> 12) * srowpixels + (curx >> 12)]; } if ((int)nexty >= 0 && nexty < maxy && (int)nextx >= 0 && nextx < maxx) { pix3 = new rgb_t(source.get_uint32((int)((nexty >> 12) * srowpixels + (nextx >> 12)))); // source[(nexty >> 12) * srowpixels + (nextx >> 12)]; } /* compute the x/y scaling factors */ curx &= 0xfff; cury &= 0xfff; /* contributions from pixel 0 (top,left) */ factor = (0x1000 - curx) * (0x1000 - cury); sumr = factor * pix0.r(); sumg = factor * pix0.g(); sumb = factor * pix0.b(); suma = factor * pix0.a(); /* contributions from pixel 1 (top,right) */ factor = curx * (0x1000 - cury); sumr += factor * pix1.r(); sumg += factor * pix1.g(); sumb += factor * pix1.b(); suma += factor * pix1.a(); /* contributions from pixel 2 (bottom,left) */ factor = (0x1000 - curx) * cury; sumr += factor * pix2.r(); sumg += factor * pix2.g(); sumb += factor * pix2.b(); suma += factor * pix2.a(); /* contributions from pixel 3 (bottom,right) */ factor = curx * cury; sumr += factor * pix3.r(); sumg += factor * pix3.g(); sumb += factor * pix3.b(); suma += factor * pix3.a(); /* apply scaling */ suma = (suma >> 24) * a / 256; sumr = (sumr >> 24) * r / 256; sumg = (sumg >> 24) * g / 256; sumb = (sumb >> 24) * b / 256; /* if we're translucent, add in the destination pixel contribution */ if (a < 256) { rgb_t dpix = new rgb_t(dest.get_uint32((int)(y * drowpixels + x))); // dest[y * drowpixels + x]; suma += dpix.a() * (256 - a); sumr += dpix.r() * (256 - a); sumg += dpix.g() * (256 - a); sumb += dpix.b() * (256 - a); } /* store the target pixel, dividing the RGBA values by the overall scale factor */ dest.set_uint32((int)(y * drowpixels + x), new rgb_t((byte)suma, (byte)sumr, (byte)sumg, (byte)sumb)); // dest[y * drowpixels + x] = new rgb_t((byte)suma, (byte)sumr, (byte)sumg, (byte)sumb); } } }
public override void init(running_machine machine) { // call our parent base.init(machine); set_verbose(true); string stemp; osd_options_WinForms options = (osd_options_WinForms)machine.options(); // determine if we are benchmarking, and adjust options appropriately int bench = options.bench(); if (bench > 0) { options.set_value(emu_options.OPTION_THROTTLE, 0, OPTION_PRIORITY_MAXIMUM); options.set_value(osd_options.OSDOPTION_SOUND, "none", OPTION_PRIORITY_MAXIMUM); options.set_value(osd_options.OSDOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); options.set_value(emu_options.OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); } // determine if we are profiling, and adjust options appropriately int profile = options.profile(); if (profile > 0) { options.set_value(emu_options.OPTION_THROTTLE, 0, OPTION_PRIORITY_MAXIMUM); options.set_value(osd_options.OSDOPTION_NUMPROCESSORS, 1, OPTION_PRIORITY_MAXIMUM); } #if false // thread priority if ((machine.debug_flags_get() & running_machine.DEBUG_FLAG_OSD_ENABLED) == 0) SetThreadPriority(GetCurrentThread(), options.priority()); #endif // get number of processors stemp = options.numprocessors(); #if false osd_num_processors = 0; if (stemp != "auto") { osd_num_processors = Convert.ToInt32(stemp); if (osd_num_processors < 1) { osdcore_global.m_osdcore.osd_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n"); osd_num_processors = 0; } } #endif // initialize the subsystems init_subsystems(); #if false // notify listeners of screen configuration string tempstring; for (win_window_info info = win_window_list; info != null; info = info.m_next) { string tmp = utf8_from_tstring(info.m_monitor.info.szDevice); string tempstring = string.Format("Orientation({0})", tmp); output_set_value(tempstring, info.m_targetorient); //osd_free(tmp); } #endif // hook up the debugger log if (options.oslog()) machine.add_logerror_callback(osdcore_interface.osd_printf_debug); #if false // crank up the multimedia timer resolution to its max // this gives the system much finer timeslices timeresult = timeGetDevCaps(&timecaps, sizeof(timecaps)); if (timeresult == TIMERR_NOERROR) timeBeginPeriod(timecaps.wPeriodMin); #endif #if false // if a watchdog thread is requested, create one int watchdog = options.watchdog(); if (watchdog != 0) { watchdog_reset_event = CreateEvent(NULL, FALSE, FALSE, NULL); emucore_global.assert_always(watchdog_reset_event != null, "Failed to create watchdog reset event"); watchdog_exit_event = CreateEvent(NULL, TRUE, FALSE, NULL); emucore_global.assert_always(watchdog_exit_event != null, "Failed to create watchdog exit event"); watchdog_thread = CreateThread(NULL, 0, watchdog_thread_entry, (LPVOID)(FPTR)watchdog, 0, NULL); emucore_global.assert_always(watchdog_thread != null, "Failed to create watchdog thread"); } #endif #if false // create and start the profiler if (profile > 0) { profiler = new sampling_profiler(1000, profile - 1)); profiler.start(); } #endif #if false // initialize sockets win_init_sockets(); #endif #if false // note the existence of a machine g_current_machine = &machine; #endif ///////////////////////////////////////////// // custom code below validity_checker valid = new validity_checker(machine.options()); valid.set_validate_all(true); string sysname = machine.options().system_name(); bool result = valid.check_all_matching(string.IsNullOrEmpty(sysname) ? "*" : sysname); if (!result) throw new emu_fatalerror(main_global.EMU_ERR_FAILED_VALIDITY, "Validity check failed ({0} errors, {1} warnings in total)\n", valid.errors(), valid.warnings()); valid.Dispose(); /** * Save away the machine, we'll need it in osd_customize_input_type_list **/ //g_state.machine = machine; /** * Create the render_target that tells MAME the rendering parameters it * will use. **/ m_target = machine.render().target_alloc(); /** * Have this target hold every view since we only support one target **/ m_target.set_view(m_target.configured_view("auto", 0, 1)); /** * Set render target bounds to 10000 x 10000 and allow the callback to * scale that to whatever they want. **/ //m_target.set_bounds(640, 480, 1.0f); m_target.set_bounds(400, 400, 1.0f); screenbufferptr = new RawBufferPointer(screenbuffer); { keyboard_state = new intref[(int)input_item_id.ITEM_ID_ABSOLUTE_MAXIMUM]; for (int i = 0; i < (int)input_item_id.ITEM_ID_ABSOLUTE_MAXIMUM; i++) keyboard_state[i] = new intref(); input_device keyboard_device; keyboard_device = machine.input().device_class(input_device_class.DEVICE_CLASS_KEYBOARD).add_device("Keyboard", "Keyboard0"); if (keyboard_device == null) throw new emu_fatalerror("osd_interface.init() - FAILED - add_device() failed\n"); foreach (var entry in mameForm.Form1.keymap) { string defname = entry.Key.ToString(); //string.Format("Scan{0}", count++); input_item_id itemid = entry.Value; keyboard_device.add_item(defname, itemid, keyboard_get_state, keyboard_state[(int)itemid]); } } { mouse_axis_state = new intref[2]; for (int i = 0; i < 2; i++) mouse_axis_state[i] = new intref(); input_device mouse_device; mouse_device = machine.input().device_class(input_device_class.DEVICE_CLASS_MOUSE).add_device("Mouse", "Mouse0"); if (mouse_device == null) throw new emu_fatalerror("osd_interface.init() - FAILED - add_device() failed\n"); string defname; defname = string.Format("X {0}", mouse_device.name()); mouse_device.add_item(defname, input_item_id.ITEM_ID_XAXIS, mouse_axis_get_state, mouse_axis_state[0]); defname = string.Format("Y {0}", mouse_device.name()); mouse_device.add_item(defname, input_item_id.ITEM_ID_YAXIS, mouse_axis_get_state, mouse_axis_state[1]); mouse_button_state = new intref[5]; for (int i = 0; i < 5; i++) mouse_button_state[i] = new intref(); defname = string.Format("B1"); mouse_device.add_item(defname, input_item_id.ITEM_ID_BUTTON1, mouse_button_get_state, mouse_button_state[0]); defname = string.Format("B2"); mouse_device.add_item(defname, input_item_id.ITEM_ID_BUTTON2, mouse_button_get_state, mouse_button_state[1]); defname = string.Format("B3"); mouse_device.add_item(defname, input_item_id.ITEM_ID_BUTTON3, mouse_button_get_state, mouse_button_state[2]); defname = string.Format("B4"); mouse_device.add_item(defname, input_item_id.ITEM_ID_BUTTON4, mouse_button_get_state, mouse_button_state[3]); defname = string.Format("B5"); mouse_device.add_item(defname, input_item_id.ITEM_ID_BUTTON5, mouse_button_get_state, mouse_button_state[4]); } //System.Windows.Forms.Application.Run(new mameForm.Form1()); //System.Windows.Forms.Form mainForm = new mameForm.Form1(); //mainForm.FormClosed += (_sender, _args) => { System.Windows.Forms.Application.ExitThread(); }; //mainForm.Show(); //Console.WriteLine("After Show()"); }