Esempio n. 1
0
//============================================================
// switchres_modeline_setup
//
//============================================================
bool switchres_modeline_setup(running_machine &machine)
{
    ModeLine *bestMode;
    char modeline[1024]= {'\x00'};
    bool success = false;
    int got_res = 0;

    mame_printf_verbose("SwitchRes: Entering switchres_modeline_setup (%d)\n",
                        machine.switchRes.resolution.count);

    bestMode = &machine.switchRes.bestMode;

    windows_options &options = downcast<windows_options &>(machine.options());
    astring error_string;

    if (!machine.switchRes.resolution.count) {
        strcpy(machine.switchRes.gameInfo.resolution, options.resolution());
        machine.switchRes.cs.monitorcount = options.numscreens();
        machine.switchRes.cs.doublescan = 0;
        if (!strcmp(options.video(), "d3d")) {
            machine.switchRes.cs.cleanstretch = 1;
            options.set_value(OPTION_CLEANSTRETCH, true, OPTION_PRIORITY_MAXIMUM, error_string);
            mame_printf_verbose("SwitchRes: Setting Option -cleanstretch\n");
        }
    }

    // Save old modeline first if it exists
    if (machine.switchRes.resolution.count > 0) {
        memcpy(&machine.switchRes.lastMode, bestMode, sizeof(ModeLine));
        mame_printf_verbose("SwitchRes: Copy lastMode name %s\n",
                            machine.switchRes.lastMode.name);
    }

    // Generate modeline
    switchres_calc_modeline(machine);

    if (!machine.switchRes.modeLine) {
        mame_printf_error("SwitchRes: Modeline was NULL!!!\n");
        return false;
    }

    // Initially get the registry modelines
    if (machine.switchRes.modecount == 0) {
        int custom_count = 0;

        machine.switchRes.modecount = GetAvailableVideoModes(machine.switchRes.videoModes);
        custom_count = GetCustomVideoModes(&machine.switchRes.cs,
                                           machine.switchRes.videoModes);
        mame_printf_verbose("SwitchRes: Found %d custom of %d active modelines\n",
                            custom_count, machine.switchRes.modecount);
    }

    // If we got any, check for the best modeline
    if (machine.switchRes.modecount > 0) {
        int orientation = 0;
        if (machine.switchRes.gameInfo.orientation && !strcmp(machine.switchRes.cs.morientation, "horizontal"))
            orientation = 1;
        got_res = findBestMode(orientation, machine.switchRes.modeLine,
                               machine.switchRes.videoModes,
                               bestMode);
        mame_printf_verbose("SwitchRes: Index %d/%d modeline %s score %.02f %s\n",
                            got_res, machine.switchRes.modecount, bestMode->label, bestMode->score,
                            (got_res >= 0)?"matches":"has no match");
    } else {
        got_res = -1;
        machine.switchRes.modecount = -1;
        mame_printf_error("SwitchRes: Didn't get any system or custom modelines %d\n",
                          got_res);
    }

    // If we got a best mode, setup for use
    if (got_res != -1) {
        int use_ini = strcmp(machine.switchRes.gameInfo.resolution, "auto")?1:0;
        bool virtualize = false;

        // Got a registry modeline to change refresh rate of
        mame_printf_verbose("SwitchRes: Got %s modeline %s - %s:\n\t%s\n",
                            bestMode->custom?"Custom":"System",
                            bestMode->resolution, bestMode->label,
                            PrintModeline(bestMode, modeline));

        // Tweak modeline if height/width changed
        if (machine.switchRes.modeLine->hactive != bestMode->a_width
                || machine.switchRes.modeLine->vactive != bestMode->a_height)
        {
            int minwidth = machine.switchRes.modeLine->hactive;

            // Turn off .ini file support, since we can't do that
            use_ini = 0;

            // Use values from registry
            machine.switchRes.gameInfo.width = bestMode->a_width;
            machine.switchRes.gameInfo.height = bestMode->a_height;

            mame_printf_verbose("SwitchRes: Trying to recalculate modeline %d x %d != %d x %d\n",
                                machine.switchRes.modeLine->hactive,
                                machine.switchRes.modeLine->vactive,
                                bestMode->a_width, bestMode->a_height);

            // Generate new modeline
            ModelineCreate(&machine.switchRes.cs,
                           &machine.switchRes.gameInfo,
                           machine.switchRes.monitorMode,
                           machine.switchRes.modeLine);
            machine.switchRes.modeLine->weight =
                ModelineResult(machine.switchRes.modeLine,
                               &machine.switchRes.cs);

            // Double check the height/width, recalculate if necessary
            if (machine.switchRes.modeLine->hactive != bestMode->a_width
                    || machine.switchRes.modeLine->vactive != bestMode->a_height)
            {
                mame_printf_verbose("SwitchRes: Trying again to recalculate modeline %d x %d != %d x %d\n",
                                    machine.switchRes.modeLine->hactive,
                                    machine.switchRes.modeLine->vactive,
                                    bestMode->a_width, bestMode->a_height);

                if (machine.switchRes.modecount > 0) {
                    int orientation = 0;
                    int idx = 0;
                    if (machine.switchRes.gameInfo.orientation
                            && !strcmp(machine.switchRes.cs.morientation, "horizontal"))
                        orientation = 1;

                    idx = findBestMode(orientation, machine.switchRes.modeLine,
                                       machine.switchRes.videoModes, bestMode);

                    mame_printf_verbose("SwitchRes: Recalculated index %d/%d modeline %s score %.02f %s\n",
                                        idx, machine.switchRes.modecount, bestMode->label, bestMode->score,
                                        (got_res >= 0)?"matches":"has no match");

                    if (idx) {
                        if (bestMode->custom) {
                            mame_printf_verbose("SwitchRes: Got %s modeline %s - %s:\n\t%s\n",
                                                bestMode->custom?"Custom":"System",
                                                bestMode->resolution, bestMode->label,
                                                PrintModeline(bestMode, modeline));
                        } else {
                            mame_printf_verbose("SwitchRes: Got %s modeline %s\n",
                                                bestMode->custom?"Custom":"System",
                                                bestMode->label);
                        }
                        machine.switchRes.gameInfo.width = bestMode->a_width;
                        machine.switchRes.gameInfo.height = bestMode->a_height;
                    } else
                        virtualize = true;
                } else
                    virtualize = true;
                if (virtualize)
                    mame_printf_error("SwitchRes: Failed at finding a good modeline!!!\n");
            }

            // Check if aspect ratio needs to be fixed
            if (bestMode->a_width > minwidth) {
                mame_printf_verbose("SwitchRes: Setting Option -keepaspect\n");
                options.set_value(WINOPTION_KEEPASPECT, true, OPTION_PRIORITY_MAXIMUM, error_string);
            }

            PrintModeline(machine.switchRes.modeLine, modeline);
            mame_printf_verbose("SwitchRes: New Modeline: \tModeLine     %s\n",
                                modeline);
        }

        // Set new resolution settings and reload it into the system
        if (!bestMode->custom || virtualize) {
            machine.switchRes.modeLine->result |= RESULT_VFREQ_CHANGE;
            success = true;
        } else if (!SetCustomVideoModes(&machine.switchRes.cs,
                                        bestMode, machine.switchRes.modeLine, 0))
        {
            ResetVideoModes();
            success = true;
        } else {
            machine.switchRes.modeLine->result |= RESULT_VIRTUALIZE;
            mame_printf_error("SwitchRes: Failed setting modeline!!!\n");
            success = false;
        }

        // Calculate flags to set options
        CalculateMameOptions(machine);

        // If not virtualizing, do 1:1 scaling from original for height/width
        if (!(machine.switchRes.modeLine->result & RESULT_VIRTUALIZE)) {
            if ((machine.switchRes.modeLine->result & (RESULT_RES_INC|RESULT_RES_DEC)))
                virtualize = true;
        } else
            virtualize = true;

        if (virtualize) {
            // Adjust settings if stretched resolution
            mame_printf_verbose("SwitchRes: Setting Option -hwstretch\n");
            options.set_value(WINOPTION_HWSTRETCH, true, OPTION_PRIORITY_MAXIMUM, error_string);
            mame_printf_verbose("SwitchRes: Setting Option -keepaspect\n");
            options.set_value(WINOPTION_KEEPASPECT, true, OPTION_PRIORITY_MAXIMUM, error_string);

            // Aspect ratio specified
            if ((machine.switchRes.gameInfo.orientation && !strcmp(machine.switchRes.cs.morientation, "horizontal")) ||
                    (!machine.switchRes.gameInfo.orientation && !strcmp(machine.switchRes.cs.morientation, "vertical")))
            {
                mame_printf_verbose("SwitchRes: Setting Option -screen_aspect %s\n", machine.switchRes.cs.aspect);
                options.set_value(WINOPTION_ASPECT, machine.switchRes.cs.aspect, OPTION_PRIORITY_MAXIMUM, error_string);
            }
        }

        // If interlacing, we need the filter on
        if (bestMode->interlace) {
            mame_printf_verbose("SwitchRes: Setting Option -filter\n");
            options.set_value(WINOPTION_FILTER, true, OPTION_PRIORITY_MAXIMUM, error_string);
        }

        // Only use soundsync if set by user and also vsync doesn't match, else turn it off
        if (machine.switchRes.modeLine->result & RESULT_VFREQ_CHANGE) {
            if (machine.options().soundsync()) {
                mame_printf_verbose("SwitchRes: Setting Option -soundsync\n");
                machine.switchRes.cs.soundsync = 1;
            }
        } else {
            mame_printf_verbose("SwitchRes: Setting Option -nosoundsync\n");
            machine.switchRes.cs.soundsync = 0;
        }

        if ((machine.switchRes.modeLine->result & RESULT_VFREQ_CHANGE && !options.sync_refresh()) || options.triple_buffer()) {
            // Resolution doesn't match refresh rate
            mame_printf_verbose("SwitchRes: Disabling VSYNC\n");
            mame_printf_verbose("SwitchRes: Setting Option -throttle\n");
            options.set_value(OPTION_THROTTLE, true, OPTION_PRIORITY_MAXIMUM, error_string);
            mame_printf_verbose("SwitchRes: Setting Option -nowaitvsync\n");
            options.set_value(WINOPTION_WAITVSYNC, false, OPTION_PRIORITY_MAXIMUM, error_string);
        } else {
            // Resolution matches refresh rate
            mame_printf_verbose("SwitchRes: Enabling VSYNC\n");
            mame_printf_verbose("SwitchRes: Setting Option -nothrottle\n");
            options.set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM, error_string);
            mame_printf_verbose("SwitchRes: Setting Option -waitvsync\n");
            options.set_value(WINOPTION_WAITVSYNC, true, OPTION_PRIORITY_MAXIMUM, error_string);
        }

        // Force resolution
        if (!use_ini) {
            sprintf(machine.switchRes.bestMode.resolution, "%dx%d@%d",
                    machine.switchRes.bestMode.hactive, machine.switchRes.bestMode.vactive,
                    (int)machine.switchRes.bestMode.vfreq);

            mame_printf_verbose("SwitchRes: Setting Option -resolution %s\n", machine.switchRes.bestMode.resolution);
            options.set_value(WINOPTION_RESOLUTION, machine.switchRes.bestMode.resolution,
                              OPTION_PRIORITY_MAXIMUM, error_string);

            // Setup video config resolution parameters screen 1
            video_config.window[0].refresh = (int)machine.switchRes.bestMode.vfreq;
            video_config.window[0].width = machine.switchRes.bestMode.a_height;
            video_config.window[0].height = machine.switchRes.bestMode.a_width;
        } else
            mame_printf_verbose("SwitchRes: INI File resolution: %dx%d@%d\n",
                                video_config.window[0].width, video_config.window[0].height,
                                video_config.window[0].refresh);

        machine.switchRes.cs.cleanstretch = machine.options().cleanstretch();

        machine.switchRes.resolution.count++;
    } else {
        mame_printf_error("SwitchRes: Couldn't find a working resolution for %dx%d@%d\n",
                          machine.switchRes.modeLine->hactive,
                          machine.switchRes.modeLine->vactive,
                          (int)machine.switchRes.gameInfo.refresh);
    }
    return success;
}
Esempio n. 2
0
int
main (int argc, char *argv[])
{
    DisplayModeRec  *Mode;
    int  HDisplay = 0, VDisplay = 0;
    float  VRefresh = 0.0;
    Bool  Reduced = FALSE, Verbose = FALSE, IsCVT;
    Bool  Interlaced = FALSE;
    int  n;

    if ((argc < 3) || (argc > 7)) {
        PrintUsage(argv[0]);
        return 1;
    }

    /* This doesn't filter out bad flags properly. Bad flags get passed down
     * to atoi/atof, which then return 0, so that these variables can get
     * filled next time round. So this is just a cosmetic problem.
     */
    for (n = 1; n < argc; n++) {
        if (!strcmp(argv[n], "-r") || !strcmp(argv[n], "--reduced"))
            Reduced = TRUE;
        else if (!strcmp(argv[n], "-i") || !strcmp(argv[n], "--interlaced"))
            Interlaced = TRUE;
        else if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--verbose"))
            Verbose = TRUE;
        else if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help")) {
            PrintUsage(argv[0]);
            return 0;
        } else if (!HDisplay) {
            HDisplay = atoi(argv[n]);
	    if (!HDisplay) {
		PrintUsage(argv[0]);
		return 1;
	    }
	}
        else if (!VDisplay) {
            VDisplay = atoi(argv[n]);
	    if (!VDisplay) {
		PrintUsage(argv[0]);
		return 1;
	    }
	}
        else if (!VRefresh) {
            VRefresh = atof(argv[n]);
	    if (!VRefresh) {
		PrintUsage(argv[0]);
		return 1;
	    }
	}
        else {
            PrintUsage(argv[0]);
            return 1;
        }
    }

    if (!HDisplay || !VDisplay) {
        PrintUsage(argv[0]);
        return 0;
    }

    /* Default to 60.0Hz */
    if (!VRefresh)
        VRefresh = 60.0;

    /* Horizontal timing is always a multiple of 8: round up. */
    if (HDisplay & 0x07) {
        HDisplay &= ~0x07;
        HDisplay += 8;
    }

    if (Reduced) {
	if ((VRefresh / 60.0) != floor(VRefresh / 60.0)) {
	    fprintf(stderr,
		    "\nERROR: Multiple of 60Hz refresh rate required for "
		    " reduced blanking.\n");
	    PrintUsage(argv[0]);
	    return 0;
	}
    }

    IsCVT = CVTCheckStandard(HDisplay, VDisplay, VRefresh, Reduced, Verbose);

    Mode = xf86CVTMode(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);

    PrintComment(Mode, IsCVT, Reduced);
    PrintModeline(Mode, HDisplay, VDisplay, VRefresh, Reduced);
    
    return 0;
}