Доброго времени суток, уважаемые хаброжители.

На днях у меня появилась идея написать Game Boy, на чистом CSS.

После того как Game Boy был реализован, прибывая на codepen, поступали разные интересные предложения, о том, как бы оживить его.

По мере того как Game Boy приобретал своих сторонников, я решил опубликовать статью: «Как я написал Game Boy » и подключил эмулятор.

Рабочая версия Дубасим: в старый добрый «Mario».

Среда для разработки Sublime text и webkit браузер.

Работа оказалась абсолютно не сложная, скорее увлекательная.

image

Полагаю, вы хорошо знакомы с CSS, Javascript, HTML5, и вам не составит труда разобраться в моей писанине.
В HTML разметке присутствуют комментарии к дивам.

1. HTML, Javascript

<body>
	<div class="wrapper"> Тело геймбоя, я поместил под элементом враппер, мозила  и експлорер, почему-то игнорируют градиентный бекгаунд у элемента body  (если в родителе есть потомок с абсолютным позиционированием.) Решение проблемы я не нашел,  по сему пришлось сделать вот такую мутку .
		<p>by ANTON ESSENTIAL</p>
	</div>
	<div class="gameboy"> Тело геймбоя
		<hr class="l-1">
		<hr class="l-2">
		<hr class="l-3">
		<hr class="l-4">
		<hr class="l-5">
		<hr class="l-6">
		<hr class="l-7">
		<hr class="l-8">
		<p>dot matrix with stereo sound</p> 
		<div class="reflex"> 
			<div class="display-2"></div>   Дисплей 
			<canvas id="LCD" width='147' height='134'></canvas> Дисплей 
			<div class="display"></div>  Див с эффектом (эффект пластика на дисплеей) 
			<span class="diod"></span>  Диод 
		</div>
		<ul class="buttons"> <b>Кнопки (А.B)</b>
			<li></li>
			<li></li>
		</ul>
		<ul class="buttons-2"><b> Кнопки (Start, Select)</b>
			<li class='start' onclick='gb_Run();'></li>
			<li class='pause' disabled onclick='gb_Pause();'></li>
		</ul>
		<ul class="speacker">  Динамик 
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<div class="stick">  Стик 
			<ul class="left">
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
			<ul class="right">
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
			<ul class="top">
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
			<ul class="bottom">
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
			<ul class="circle">
				<li></li>
			</ul>
		</div>
	</div>

	<select id="CARTRIDGE" row='1' onchange='gb_Insert_Cartridge(this.value,true);'>   Селектор образов (картриджы) 
          <option value="Super-Mario-Land.gb">Super-Mario-Land</option>
          <option value="mc-mrder.gb">PD mc-mrder</option>
          <option value="20y.gb">PD 20y</option>
          <option value="wario_walking.gb">PD wario_walking</option>
	</select><br>
	<input id='BR' type="button" value='Run' onfocus='this.blur();' onclick='gb_Run();'>    Управление 
	<input id='BP' type="button" value='Pause' onfocus='this.blur();' disabled onclick='gb_Pause();'>
	<input id='BS' type="button" value='Step' onfocus='this.blur();' onclick='gb_Step();'>
	<input id="BS" type="button" value="Reset"  onfocus="this.blur();" onclick="gb_Insert_Cartridge($('CARTRIDGE').value,true);"/>
	<input id='BX' type="button" value='Size x2' onfocus='this.blur();' onclick='gb_Resize_LCD();'>
	<div id="DEBUGGER"></div>

	<script type='text/javascript' src='js/cssrefresh.js'></script>
	<script type='text/javascript' src='js/jquery-1.10.2.min.js'></script>
	<script type='application/x-javascript' src='js/toolbox.js'></script>
	<script type='application/x-javascript' src='js/scrollbar.js'></script>
	<script type='application/x-javascript' src='js/jsgb.cpu.js'></script>
	<script type='application/x-javascript' src='js/jsgb.memory.js'></script>
	<script type='application/x-javascript' src='js/jsgb.rom.js'></script>
	<script type='application/x-javascript' src='js/jsgb.interrupts.js'></script>
	<script type='application/x-javascript' src='js/jsgb.input.js'></script>
	<script type='application/x-javascript' src='js/jsgb.lcd.js'></script>
	<script type='application/x-javascript' src='js/jsgb.timers.js'></script>
	<script type='application/x-javascript' src='js/jsgb.debugger.js'></script>
	<script type='application/x-javascript' src='js/jsgb.gameboy.js'></script>

	<script type='application/x-javascript'>   Ресайз дисплея 

		var gbSeconds = 0;
		var gbFrames = 0;

		function gb_Resize_LCD() {
			if($('BX').value=='Size x2') {
				$('BX').value='Size x3';
				$('LCD').style.width='320px';
				$('LCD').style.heght='288px';
			}
			else if($('BX').value=='Size x3') {
				$('BX').value='Size x1';
				$('LCD').style.width='480px';
				$('LCD').style.heght='432px';
			}
			else {
				$('BX').value='Size x2';
				$('LCD').style.width='147px';
				$('LCD').style.heght='134px';
			}
		}

		function gb_Show_Fps() {
			gbFrames+=gbFPS;
			gbSeconds++;
			$('STATUS').innerHTML =
				'Running: '+gbFPS+' '+
				'fps - Averenge: '+(gbFrames/gbSeconds).toFixed(2)+' - '+
				'Bank switches/s: '+gbBankSwitchCount;
			gbFPS=0;
			gbBankSwitchCount=0;
		}

		function gb_Toggle_Debugger(show) {
			$('DEBUGGER').style.heght=(show)?'auto':'0px';
		}

		window.onload = function(){
			gb_Insert_Cartridge($('CARTRIDGE').value, false);
			gb_Toggle_Debugger($('TOGGLE_DEBUGGER').checked);
		}

	</script>

	<script>   По событию клик, появляется канвас [дисплей] 
		jQuery(function($) {
			$('.start').click(function(){
				$('#LCD').fadeIn(1);
			});
		});
	</script>
</body>
</html>


В представленном ниже коде, я не буду упоминать про резет, либо нармолайз цсс.
Так же я опустил префиксы, чтобы сэкономить время.

2. CSS
body {
	background: rgb(32, 32, 32);
}

.wrapper {
	position: relative;
	top: 50px;
	width: 100%;
	height: 645px;
	background-image: linear-gradient(-32deg,#e41717, #72075c 78%);
	-webkit-filter: blur(2px);
}

.gameboy {
	position: absolute;
	top: 150px;
	left: 200px;
	width: 265px;
	height: 433px;
	border: 2px solid rgb(153, 153, 153);
	border-radius: 10px 10px 77px 10px;
	background-image: -webkit-linear-gradient(#adb6b3, #bec2c1 50%);
	box-shadow: -5px 6px 20px rgba(0, 0, 0, 0.46),
	-21px 17px 65px rgba(0, 0, 0, 0.46),
	inset 3px 0 10px #616465,
	inset -3px 0 4px #8e918e,
	inset -7px 0 7px #dfdfdf,
	inset 1px 0px 3px #66696a,
	inset 0 3px 7px #919496,
	inset 0 4px 10px white;
}

.wrapper p {
	position: relative;
	top: 511px;
	left: 534px;
	display: inline-block;
	color: white;
	font-weight: bold;
	font-size: 26px;
	font-family: "Arial"
}

.gameboy p {
	position: absolute;
	top: 45px;
	left: 85px;
	z-index: 2;
	color: rgba(255, 255, 255, 0.63);
	text-transform: uppercase;
	font-size: 7px;
	font-family: "Arial"
}

.reflex {
	position: relative;
	top: 36px;
	left: 15px;
	overflow: hidden;
	width: 232px;
	height: 177px;
	border-top: 1px solid #3d4844;
	border-right: 1px solid #3d4844;
	border-bottom: 1px solid #1d2120;
	border-left: 2px solid rgba(29, 33, 32, 0.57);
	border-radius: 10px 10px 53px 10px;
	background: #485055;
	box-shadow: inset 0 1px 1px #aab3b0,
	0 1px 0 #5b5e63,
	0 2px 0 #ebebeb,
	1px 0 2px #d3d3d3,
	-1px 0 2px #cfcfcf,
	inset -1px 0 2px rgba(255, 255, 255, 0.44);
}

.display {
	position: absolute;
	z-index: 3;
	width: 232px;
	height: 177px;
	border-radius: 10px 10px 53px 10px;
	background-image: -webkit-linear-gradient(46deg, rgba(72, 80,85, 0), rgba(143, 151, 156, 0.58)80%);
}

.display-2 {
	position: absolute;
	top: 21px;
	left: 43px;
	z-index: 2;
	width: 147px;
	height: 134px;
	border-top: 1px solid #394b21;
	border-right: 1px solid #36472f;
	background: #5f953d;
	box-shadow: inset -2px 5px 10px #2a421a;
	opacity: .5;
}

#LCD {
	display: none;
	position: absolute;
	top: 21px;
	left: 43px;
}

.l-1 {
	position: absolute;
	top: 11px;
	width: 265px;
	height: 3px;
	border: none;
	border-radius: 50px;
	background-image: -webkit-linear-gradient(#87928d, #a9b2af 90%);
	opacity: .6;
}

.l-2 {
	position: absolute;
	top: -8px;
	left: 20px;
	width: 3px;
	height: 19px;
	border: none;
	border-radius: 5px 5px 0 0;
	background-image: -webkit-linear-gradient(#a9b2af, #87908d 90%);
	opacity: .6;
}

.l-3 {
	position: absolute;
	top: -8px;
	right: 20px;
	width: 3px;
	height: 19px;
	border: none;
	border-radius: 5px 5px 0 0;
	background-image: -webkit-linear-gradient(#a9b2af, #87908d 90%);
	opacity: .6;
}

.l-4 {
	position: absolute;
	top: 36px;
	left: 26px;
	z-index: 2;
	width: 51px;
	height: 3px;
	border: none;
	background: #543363;
}

.l-5 {
	position: absolute;
	top: 42px;
	left: 26px;
	z-index: 2;
	width: 51px;
	height: 3px;
	border: none;
	background: #30345a;
}

.l-6 {
	position: absolute;
	top: 36px;
	left: 217px;
	z-index: 2;
	width: 20px;
	height: 3px;
	border: none;
	background: #543363;
}

.l-7 {
	position: absolute;
	top: 42px;
	left: 217px;
	z-index: 2;
	width: 20px;
	height: 3px;
	border: none;
	background: #30345a;
}

.l-8 {
	position: absolute;
	display: none;
}

.diod {
	position: absolute;
	top: 61px;
	left: 12px;
	display: block;
	width: 9px;
	height: 9px;
	border: 1px solid #ac774d;
	border-radius: 50px;
	background: #e4b443;
	box-shadow: 0 0 5px #ac774d,
	-1px 1px 1px rgba(83, 53, 41, 0.99),
	inset 0 1px 2px #fcb251;
	-webkit-animation:light linear 3s infinite;
}

.buttons {
	position: absolute;
	top: 242px;
	left: 179px;
	padding: 6px;
	border-radius: 50px;
	box-shadow: 1px 1px 5px rgba(255, 255, 255, 0.21),
	-1px 1px 0px #babdbc,
	inset 0 12px 22px rgba(0, 0, 0, 0.12);
	-webkit-transform: rotate(64deg);
}

.buttons li {
	width: 30px;
	height: 30px;
	border: 1px solid rgba(68, 32, 54, 1);
	border-radius: 100%;
	background-image: linear-gradient(6deg,rgba(133, 50, 108, 0.61),#6d1851 89%);
	box-shadow: inset 1px 2px 4px #a87493,
	-1px -1px 2px #000,
	3px 6px 7px rgba(125, 136, 134, 0.79);
}

.buttons li:first-child {
	margin-bottom: 17px;
}

.buttons-2 {
	position: absolute;
	top: 348px;
	left: 103px;
	-webkit-transform: rotate(64deg);
}

.buttons-2 li {
	position: absolute;
	width: 9px;
	height: 34px;
	border-radius: 50px;
	background-image: linear-gradient(269deg, #6f7875, #9b9b9b 71%);
	box-shadow: 1px 1px 1px rgba(226, 226, 226, 0.97),
	-1px -1px 2px #767a79,
	inset 1px 1px 1px #a3aca9;
}

.buttons-2 li:last-child {
	position: absolute;
	bottom: 7px;
	left: 20px;
}

.speacker {
	position: absolute;
	top: 344px;
	left: 174px;
	-webkit-transform: rotate(64deg);
}

.speacker li {
	margin-bottom: 8px;
	width: 42px;
	height: 6px;
	border-radius: 10px;
	box-shadow: 1px 1px 1px rgba(255, 255, 255, 0.7),
	inset 2px 1px 3px #5b5a53,
	inset 1px -1px black;
}

.stick {
	position: absolute;
	top: 252px;
	left: 14px;
	width: 93px;
	height: 93px;
	border-radius: 50%;
	box-shadow: inset -7px 10px 22px #c7cbca,
	inset 7px -10px 22px #b8b8b8;
}

.top {
	position: absolute;
	top: 15px;
	left: 34px;
	width: 24px;
	height: 21px;
	border-radius: 2px 2px 0 0;
	background-image: linear-gradient(90deg,#282c2b, #9b9b9b 119%);
	box-shadow: 1px -1px 1px rgb(53, 53, 53),
	-4px 3px 7px rgba(96, 96, 98, 0.64);
}

.top li {
	margin: 2px;
	width: 20px;
	height: 2px;
	border-radius: 2px;
	background: #353837;
	box-shadow: inset 0 -1px 1px #494c4b;
}

.left {
	position: absolute;
	top: 36px;
	left: 56px;
	width: 24px;
	height: 22px;
	border-radius: 2px 2px 0 0;
	background-image: linear-gradient(303deg,#282c2b, #9b9b9b 111%);
	box-shadow: 1px -1px 1px rgb(53, 53, 53);
	-webkit-transform: rotate(90deg);
}

.left li {
	margin: 2px;
	width: 20px;
	height: 2px;
	border-radius: 2px;
	background: #353837;
	box-shadow: inset 0 -1px 1px #494c4b;
}

.bottom {
	position: absolute;
	top: 58px;
	left: 34px;
	width: 24px;
	height: 21px;
	border-radius: 0 0 2px 2px;
	background-image: linear-gradient(55deg,#131716, #6a706f 147%);
	box-shadow: -5px 0px 6px #606362;
}

.bottom li {
	margin: 2px;
	width: 20px;
	height: 2px;
	border-radius: 2px;
	background: #050908;
	box-shadow: inset 0 -1px 1px #343839;
}

.right {
	position: absolute;
	top: 36px;
	left: 12px;
	width: 24px;
	height: 22px;
	border-radius: 0 0 2px 2px;
	background-image: linear-gradient(290deg,#131716, #6a706f 173%);
	box-shadow: 2px 3px 7px rgb(53, 53, 53);
	-webkit-transform: rotate(90deg);
}

.right li {
	margin: 2px;
	width: 20px;
	height: 2px;
	border-radius: 2px;
	background: #050908;
	box-shadow: inset 0 -1px 1px #433839;
}

.circle {
	position: absolute;
	top: 36px;
	left: 35px;
	z-index: 5;
	width: 22px;
	height: 22px;
	background-image: linear-gradient(-134deg, #656666, #2e3231 60%);
}

.circle li {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 16px;
	height: 16px;
	border: 1px solid rgba(39, 42, 41, 0.91);
	border-radius: 16px;
	background: #4b4e4d;
	box-shadow: inset 2px -1px 8px #868787,
	inset 3px -1px 10px black;
}

@-webkit-keyframes light {
	0% {
		box-shadow: 0 0 0 #ffa300;
	}
	50% {
		box-shadow: 0 0 24px #ffa300;
	}
	100% {
		box-shadow: 0 0 0 #ffa300;
	}
}

#DEBUGGER {
	visibility: hidden;
}

.start:hover,
.pause:hover {
	cursor: pointer;
}

input, select {
	position: relative;
	top: 100px;
}


Надеюсь, вам было интересно.