Difference between revisions of "Simulate CRT"

From TheAlmightyGuru
Jump to: navigation, search
Line 14: Line 14:
 
! Resolution !! Pixel Ratio !! Platforms
 
! Resolution !! Pixel Ratio !! Platforms
 
|-
 
|-
| 320x200 || 1:1.2 || [[MS-DOS]]
+
| 256x224 || 1.24:1 || [[Nintendo Entertainment System|NES]], [[Super Nintendo Entertainment System|SNES]]
 +
|-
 +
| 320x200 || 1:1.2 || [[MS-DOS]] using a [[Color Graphics Adapter|CGA]] or [[Enhanced Graphics Adapter|EGA]] in graphics mode.
 
|-
 
|-
 
| 320x240 || 1:1 || [[MS-DOS]]
 
| 320x240 || 1:1 || [[MS-DOS]]
 
|-
 
|-
| 640x350 || 1:1.371428 || [[MS-DOS]]
+
| 640x200 || 1:2.4 || [[MS-DOS]] using a [[Color Graphics Adapter|CGA]] in high-res mode.
 +
|-
 +
| 640x350 || 1:1.371428 || [[MS-DOS]] using an [[Enhanced Graphics Adapter|EGA]] in high-res mode.
 
|-
 
|-
 
| 640x400 || 1:1.2 || [[MS-DOS]]
 
| 640x400 || 1:1.2 || [[MS-DOS]]
 
|-
 
|-
| 640x480 || 1:1 || [[MS-DOS]], [[Windows 3]]
+
| 640x480 || 1:1 || [[MS-DOS]] or [[Windows 3]] using [[Video Graphics Array|VGA]].
 
|-
 
|-
| 256x224 || 1.24:1 || [[Nintendo Entertainment System|NES]], [[Super Nintendo Entertainment System|SNES]]
+
| 720x350 || 1:1.55 || [[MS-DOS]] using [[Hercules Graphics Card]] or [[IBM Monochrome Display Adapter|IBM Mono]]
 
|}
 
|}
  

Revision as of 15:52, 5 December 2018

Simulate CRT is a JScript program I wrote that distorts a screenshot to make it look like it has been displayed on a CRT monitor. It does this by adding scanlines to the image, resizing it to match the specified pixel ratio, and then distorting the image to look curved along a CRT screen. I created this script to better illustrate what classic programs looked like when played on the original hardware. This script requires that ImageMagick be installed and able to be accessed as an ActiveX object.

Here is an example of what the script can do:

CGA Example - Pal 1 - High.png
Emulated MS-DOS screenshot.

CGA Example - Simulated 320x200.png
1:1.2 pixel ratio, 25% scanlines, distorted.

Legend of Zelda, The - NES - Screenshot - Title.png
Emulated NES screenshot.

Legend of Zelda, The - NES - Screenshot - Title - Simulated CRT.png
1.24:1 pixel ratio, 25% scanlines, distorted.

You'll need to know the proper pixel aspect ratio in order to properly stretch the screen. Here are some common resolutions and what ratio they need.

Resolution Pixel Ratio Platforms
256x224 1.24:1 NES, SNES
320x200 1:1.2 MS-DOS using a CGA or EGA in graphics mode.
320x240 1:1 MS-DOS
640x200 1:2.4 MS-DOS using a CGA in high-res mode.
640x350 1:1.371428 MS-DOS using an EGA in high-res mode.
640x400 1:1.2 MS-DOS
640x480 1:1 MS-DOS or Windows 3 using VGA.
720x350 1:1.55 MS-DOS using Hercules Graphics Card or IBM Mono

Source

// This script will attempt to simulate a 4:3 CRT monitor.
// © Copyright: Dean Tersigni, 2018.
// Date Created: 2018-06-18.

// Set to the desired pixel ratio here.
var fRatioX = 1.0;
var fRatioY = 1.2;

// Set to the desired scanline visibility percentage.
var iScanlinePercent = 25;

var oArguments = WScript.Arguments;
var iArgumentCount = oArguments.Length;

// Verify that at least one argument was passed in.
if(iArgumentCount == 0) {
	WScript.Echo("Either drop an image file onto this script or run this script by passing in the file path of an image file.");
	WScript.Quit(1);
}

var oFSO = new ActiveXObject("Scripting.FileSystemObject");
var sTempPath = oFSO.GetSpecialFolder(2) + "\\";
var iArgument = 0;

// Convert each image using ImageMagick.
var oIM = new ActiveXObject("ImageMagickObject.MagickImage.1");

// Loop through each argument.
for(iArgument = 0; iArgument < iArgumentCount; iArgument++) {
	var sFile = oArguments.Item(iArgument);
	
	// Verify that the argument is a file that exists.
	if(oFSO.FileExists(sFile) == true) {
		var sPath = oFSO.GetParentFolderName(sFile);
		var sName = oFSO.GetBaseName(sFile);
		var sExtension = oFSO.GetExtensionName(sFile);
		
		// Get the new output file name.
		var sOutput = sPath + "\\" + sName + " - " + fRatioX.toString() + "x" + fRatioY.toString() + " CRT Monitor.png";

		// Scale up by 3 before adding scanlines.
		oIM.convert(sFile,
			"-resize", "300%x300%",
			sTempPath + sName + " - CRT-x3.png");

		// Create a scanline graphic.
		oIM.convert(
			"-size", "3x3",
			"xc:transparent", 
			"+antialias",
			"-stroke", "rgba(0,0,0," + (iScanlinePercent * 0.01) + ")",
			"-fill", "rgba(0,0,0," + (iScanlinePercent * 0.01) + ")",
			"-draw", "line 0,0 2,0",
			sTempPath + sName + " - Scanlines3.png");

		// Add scanlines to the image.
		oIM.composite(
			"-tile", sTempPath + sName + " - Scanlines3.png",
			sTempPath + sName + " - CRT-x3.png",
			sTempPath + sName + " - CRT-Lines.png");
			
		// Resize the image to a correct pixel ratio.
		oIM.convert(sTempPath + sName + " - CRT-Lines.png",
			"-resize", (100 * fRatioX).toString() + "%x" + (100 * fRatioY).toString() + "%",
			sTempPath + sName + " - CRT-Ratio.png");

		// Warp the shape to resemble a CRT monitor, and shrink down to a reasonable size.
		oIM.convert(sTempPath + sName + " - CRT-Ratio.png", 
			"-background", "black",
			"-virtual-pixel", "Background", 
			"-distort", "Barrel", "0,0,0.1,0.9",
			"-gravity", "center",
			"-extent", "100%x104",
			"-resize", "640x480",
			sOutput);

		// Clean up work files.
		oFSO.DeleteFile(sTempPath + sName + " - CRT-x3.png");
		oFSO.DeleteFile(sTempPath + sName + " - Scanlines3.png");
		oFSO.DeleteFile(sTempPath + sName + " - CRT-Lines.png");
		oFSO.DeleteFile(sTempPath + sName + " - CRT-Ratio.png");
	} else {
		WScript.Echo("File: " + sFile + " does not exist.");
	}
}