"Эх вот в школе я такую программулину написал, на Паскале" - бывают такие мысли, особенно у тех кто учился, скажем, в 90е. И даже находятся порой эти старые программы на старом диске. Но если запустить их ещё в DosBox у себя на машине можно - то как показать-похвастаться другим, в интернете?
Возьмём эмулятор js-dos (им старые игры в браузере запускают) - и поколдуем над ним, чтобы можно было своими паскальными-бейсиковыми программулинами делиться всем на радость.
Пользоваться этой поделкой вы сможете не вникая в подробности! Есть страничка для подготовки ссылок с программами - хоть сразу делитесь в комментариях :) А для тех кому захочется по аналогии и другие компиляторы-интерпретаторы подключить - будет немножко пояснений что и как там сделано - чтобы форкнув код на гитхабе вы могли быстро внести нужные изменения.
Как этим пользоваться?
Нам нужна страничка в которой выполняется, например, старый добрый Quick Basic 1.1 или Turbo Pascal 5.5 (до кучи я добавил Matlab 3.05) - притом такая, чтобы ей можно было каким-то образом передать программу для загрузки и выполнения.
А как именно "передать"? Мы же по ссылке делиться будем - ну значит в параметре ссылки передавать либо целиком программу (если она небольшая) - либо урл откуда её можно взять (главное чтобы cross-origin работал).
Если хотите сразу посмотреть на результат, то вот пожалуйста:
Игра "Escape" по мотивам Ж.Арсака
В открывшемся окне вы увидите довольно знакомый интерфейс редактора Турбо-Паскаля - нажмите Ctrl-F9
(как встарь) или Alt-R
и Enter
- и программа должна запуститься. Есть и возможность автозапуска - дальше увидим.
В этой игре нужно (в пошаговом режиме) пробраться через прямоугольный зал к выходу (в левом верхнем углу) - стараясь не попасть под падающие сверху блоки. Поскольку падают они рандомно, особой стратегии тут нет. Главное долго не плутать.
Если хотите попробовать "приготовить" ссылку с собственным кодом - зайдите на центральную страничку https://rodiongork.github.io/dosprog/ - внизу есть поле для ввода программы - скопируйте туда например следующую чепуху (отредактируйте по вкусу):
program demo;
uses crt;
begin
clrscr;
gotoxy(33, 13);
writeln('I am a beautiful message!');
readln;
end.
После чего убедитесь что выбран нужный язык (паскаль в данном случае) и нажмите кнопку. Под ней появится ссылка - по этой ссылке будет открываться ваша программа, можете попробовать. Если щёлкнете чекбокс "Autorun" - программа не откроется в редакторе а сразу запустится на выполнение.
Поскольку программа может быть длинной, можно также разместить код программы где-нибудь в интернете (например на github pages как с примером выше) - и вместо самого кода использовать ссылку на него. Кроме возможности таким образом сделать большую программу с довольно короткой ссылкой это ещё и позволит редактировать впоследствии код не меняя самой ссылки.
Теперь когда в общих чертах понятно - давайте посмотрим подробности - они понадобятся если вы захотите аналогичным образом какую-то другую среду разработки запустить.
Создадим страницу с компилятором / интерпретатором
Эта часть очень простая. На сайте js-dos.com мы находим раздел Getting Started - и в нём готовый пример. В двух словах идея такая:
js-dos в себе содержит эмулятор (DosBox) скомпилированный в JavaScript
поэтому на странице вы только создаёте зону где отображать "экран" (например, во всю страницу) и вставляете ссылки на таблицу стилей и на js-файл. Их можно либо использовать либо прямо с сайта js-dos (как в примере), либо скачать себе.
создаёте "бандл" с приложением - в общем-то zip-архив, в котором лежит кроме того и конфиг для DosBox
Первые два пункта развернутых пояснений не требуют, на третий взглянем чуть подробнее.
Во-первых, как "приготовить" бандл? Если у вас уже есть zip-архив с нужной досовской программой - останется только добавить конфиг.
Если архива пока нет, удобнее всего (по-моему) DosBox запустить на локальной машине, в него скачать все что надо, установить-настроить нужную программулину - а потом её уже сархивировать в бандл. И опять же добавить конфиг.
Что там за конфиг? Обычный конфиг для DosBox - для начала можно взять тот что в примере (с диггером). В целом всевозможные настройки понятно описаны - самая важная для нас часть - в конце. Там перечислены несколько команд (на манер autoexec
) для того чтобы загрузить нужную нам программу после старта.
Конфиг укладывается в подкаталог .jsdos
с именем dosbox.conf
- типичное его окончание может выглядеть так:
[autoexec]
mount c .
c:
c:\tp\turbo.exe
Сам код для запуска бандла в странице выглядит тоже достаточно понятно - имеет смысл только добавить параметр автозапуска (иначе отображается шестерёнка которую нужно кликнуть чтобы DosBox запустился):
Dos(document.getElementById("dos"), {
url: "./my_bundle.zip",
autoStart: true,
});
Подразумевая что бандл с именем my_bundle.zip
лежит в той же директории что и сама страница - и что элемент для отображения рабочего окна программы имеет id="dos"
.
Если вы это проделаете - и запустите хотя бы локально (нужно использовать хоть простейший локальный сервер, типа busybox - или python3 -m http.server
) - то скорее всего с радостью убедитесь что программа запускается (ну, если все сделано правильно). И выдаёт картинку, например как в заголовке статьи. Или вот с матлабом вариант:
Но как подгрузить текст программы?
Вот здесь и начинаются пляски с бубном.
То что код программы мы в простейшем случае кодируем в base64
и добавляем к ссылке как значение параметра ?p=...
- это уже наверное понятно. Написать кусочек javascript чтобы взять урл текущей страницы и вытащить оттуда этот код - несложно:
let ppos = location.href.indexOf('?p=');
let data = atob(location.href.substring(ppos+3));
Это конечно упрощённый способ - мы не парсим параметры всерьёз, а просто находим нужный фрагмент с названием параметра (p), считая что параметр только один. Если вам понадобится больше - поправьте эту часть. После этого atob
расшифровывает base64
кодировку - и в общем текст нашей программы в переменной data
.
Здесь сразу добавим возможность вытащить программу из интернета, если вместо неё оказался урл:
if (data.substring(0, 5) == 'https') {
let req = new XMLHttpRequest();
req.open('GET', data, false);
req.send(null);
data = (req.status === 200) ? req.responseText : '{error loading file}';
}
Здесь мы используем синхронный XMLHttpRequest
- это не лучший вариант, но для минимизации примера пусть так останется. Как видите, в случае ошибки мы вместо результата запроса хотим показать что сообщение о неуспешной загрузке.
Важный момент - конечно сервер с которого вы грузите программу должен отдавать её с соответствующим заголовком, позволяющим загрузку в другие страницы, например:Access-Control-Allow-Origin: *
В частности github-pages
так делают, а gist.github.com
нет. Если вы захотите подгружать код с гист-гитхаб или с pastebin - скорее всего вам придётся что-то химичить.
Но это лишь пол-дела, даже наверное треть. Надо загрузить программу в наш DosBox.
Тут проблема. Конфигурация js-dos
(в джаваскрипте, не в конфиге dosbox-а) позволяет указать например параметр initFs
и dosboxConf
- первый из них позволяет добавить файлы в файловую систему, второй помогает скорректировать например строку запуска нашей программы. К сожалению оба они не работают если используется "бандл".
На эту тему даже заведён issue в гитхабе js-dos-а. Там есть мелкие технические сложности, но возможно когда-то это будет улучшено. Пока же приходится мудрить.
В параметре onEvent
можно указать функцию которая будет вызвана когда эмулятор уже загружен и в неё будет передан параметр - объект CommandInterface
- у него в частности есть методы для работы с файловой системой.
К сожалению когда эмулятор уже загружен, вроде бы уже поздно что-то грузить в файловую систему :) Во-первых наша "IDE" уже будет запущена - да и DosBox не видит новых файлов пока не выполнишь команду rescan
. Однако давайте есть слона по частям. Здесь оставим кусочек джаваскриптового кода который "забросит" нашу программу в файловую систему - а в следующем разделе разберемся как её использовать.
Dos(document.getElementById("dos"), {
url: "./my_bundle.zip",
autoStart: true,
onEvent: (event, ci) => {
if (event === "ci-ready") {
// здесь подготовим переменную "data" как показано выше
// и теперь грузим:
ci.fsWriteFile(dosprog.fname, new TextEncoder().encode(data));
}
}
});
BAT-файл для подгрузки программы
Итак, забросить файл в файловую систему эмулятора мы смогли, однако:
он её не видит пока не сделаем
rescan
поскольку всё работает асинхронно, в эмуляторе редактор может запуститься раньше чем программа будет загружена
Чтобы не дожидаться пока какую-то фичу для этого запилят в js-dos
(а может и есть какой-то ход до которого я не додумался) - можно просто написать старый-добрый досовский BAT-файл (аналог юниксовых shell
-скриптов, только проще).
Мы будем запускать этот файл из autoexec-секции в конце dosbox.conf - а что же будет в самом файле?
Будем делать rescan
, проверять, появилась ли программа на диске, и если появилась то запускаем IDE - а иначе повторяем операцию в цикле.
Один нюанс - нам нужна и возможность загружаться "начисто" - если никакой программы не передано. Ну что ж, будем в этом случае сигнализировать "добрасывая" в файловую систему пустой файл с именем, например, nofile.pas
- в общем, BAT-файл получится такой:
:repeat
rescan
if exist prg.pas goto withfile
if exist nofile.pas goto nofile
goto repeat
:withfile
\tp\turbo.exe prg.pas
goto done
:nofile
\tp\turbo.exe
:done
Как видите, циклы, goto и переходы по меткам - логика простая. Если появился файл prg.pas
- выскакиваем из цикла и переходим к запуску с файлом. Если появился файл nofile.pas
- тоже выскакиваем и переходим к запуску без файла.
В javascript есть отдельная строчка чтобы этот nofile
передать - но не будем на этом сейчас останавливаться, просто посмотрите в коде по необходимости.
Автозапуск
В качестве приятной фичи желательно добавить возможность автозапуска. В случае с бейсиком это осуществляется добавлением ключа /run
в командную строку. С турбо-паскалём я такого ключа не припомню, поэтому надо запустить компилятор tp.exe
а потом запустить скомпилированную программу. В случае матлаба файл и так запускается интерпретатором (отдельный вопрос - может это неудобно).
В общем всё это легко добавить в BAT-файл. Осталось только придумать как передать что мы хотим "автозапустить" программу. Я не придумал ничего лучше кроме как использовать ещё одно отдельное имя файла программы (например auto.pas
) и по нему выбирать какой именно режим запуска требуется.
Ну а чтобы на стороне джаваскрипта выбрать нужен ли автозапуск, условимся что это сигнализируется именем параметра в ссылке. Если это буква P
большая - значит нужен. Если p
маленькая - значит нет. Конечно это вы можете переделать на свой вкус.
На упомянутой "главной" страничке форма для создания ссылок имеет чекбокс чтобы отметить автозапуск.
Заключение
Код выложен на гитхаб - можно пользоваться как есть, можно склонировать себе и добавить любимые компиляторы и т.п.
Для удобства общий джаваскриптовый код отвечающий за запуск вынесен в файл dosprog.js
- так что если захотите добавить например Turbo C 2.0
, то вам нужны следующие шаги:
форкаем или клонируем репозиторий
копируем файл
tp55.html
например вtc20.html
- и в нём редактируем заголовок, названия файлов (вместоprg.pas
напримерprg.c
и так далее) - а также имя бандласоздаём бандл с таким именем как задали выше, в него положим кроме Turbo C также поправленный конфиг dosbox.conf и модифицированный BAT-файл (в общем-то тоже меняются имена файлов и все).
Можно было бы сделать удобнее если использовать серверную часть для хранения пользовательских программ (собственный "pastebin"), сделать пользовательские аккаунты и так далее. Но неясно насколько эта смешная поделка актуальна - кроме того тогда уже не будет так легко добавить собственные компиляторы и т.п.
Хорошо бы иметь возможность экспортировать отредактированный файл. Ведь из досбокса с экрана ничего не скопируешь. Такая возможность добавлена - если открыть консоль разработчика (Developer Console) в браузере и выполнить во вкладке console функцию в духе:
getFile("PRG.PAS")
то в консоль же будет выдана наша программа, уже закодированная в base64. Можно было бы сделать какой-то всплывающий диалог - но пока не придумал куда прилепить кнопку для его вызова. Главное - заметьте что здесь регистр имени файла различается - а в досе нет. Чаще всего файлы будут созданы с большими буквами в имени.
Переводы строк. Это больная тема - по умолчанию нередко может оказаться что они не "досовские" - и приложения типа турбо-паскаля отобразят все в одну строку. Для этого в код загрузки добавлена небольшая "автоподстановка":
data = data.replace(/(?<!=r)\n/g, '\r\n');
Не пугайтесь её - но если будут какие-то проблемы с переводами строк - вы теперь знаете где можно поправить.
Вот и всё! Можете пробовать и делиться своими историческими чудо-программами в комментариях :)
P.S. данную статью не следует рассматривать как руководство по JavaScript - автор мало знаком с ним и с фронтенд-разработкой - так что тут наверняка есть что улучшать!
Комментарии (11)
rezdm
12.11.2024 06:10Как тут не вспомнить "Трубо Паскакаль"
NeoCode
Насчет полезности запуска в браузере не знаю, а вообще интересно было бы собрать такой dosbox (или может быть virtualbox/vmware?) дистрибутив, включающий в себя множество программ тех времен. Что-то вроде виртуального рабочего места типичного айтишника 90-х. Не только с играми (хотя это наверное было бы интересно большинству) но и с другим софтом, включая средства разработки.
RodionGork Автор
ну вот это всё вы можете сделать склонировав данную репу :)
добавляете нужные вам программулины в каталог example
на главной странице делаете список ссылок для запуска этих программулин в эмуляторе
и всё :)
что касается других средств разработки - ну это чуть более телодвижений требует, как описано в статье
основная-то мысль в том что если "собрать такой досбокс" у себя на компе то шарить его неудобно (rar-архивчиком по почте что ли рассылать)
NeoCode
У меня компьютер появился в 98 году (и первой системой была win95), я почти не застал ту эпоху, но все равно испытываю к ней некую ностальгию. И софта для dos у меня было немного - Нортон коммандер, Borland C/C++ 3.1 и несколько игрушек. Но первый опыт программирования был именно для dos.
Поэтому мне было бы интересно именно скачать что-то готовое, некую коллекционную систему, собранную сообществом при участии большого числа людей. А для распространения можно использовать обычный сайт, торренты, можно даже выпускать дистрибутивы с какой-то периодичностью, вносить добавления и улучшения))
RodionGork Автор
У меня кстати тоже в 98 но это был 386 так что даже win 3.11 я лишь через несколько месяцев донёс на дискетках и с большим любопытством поставил не понимая "зачем оно".
Про коллекционную систему - мысль понятна. Просто не очень ясно как лучше сделать. В виде здоровенных образов на торрентов - этим мало кто пользоваться будет. А делать что-то объёмное ради нескольких скачиваний в месяц наверное всем лень.
Мой вариант улучшает доступность - но прям таки единого большого образа тут не создаётся (каждая программулина в общем-то в своём изолированном "бандле") - т.к. иначе пришлось бы этот мега-образ прокачивать при каждой загрузке.
В общем небольшая дилемма. Ну да хоть с чего-нибудь начнём.
goldexer
Так же примерно было, в тот же временной период. Каким же крутым тогда казался Visual Basic 6.0 (аж шесть дисков, включая FoxPro, MSDN...), со своим «просто нарисуй кнопку и пиши код в обработчике». Это после игрушечного ТП и длиннющих простыней создания окон для всего и вся на С. Delphi тогда радовал очень, я установил его на школьный комп и доспорился с учителем, что мне разрешили писать в нём. Когда у других на черном экране школьное «введите А, введите Б», тут уже было окошко с текстовыми полями, иконочками, проверкой ввода, подсказками и вообще было переносимым экзешником - кайф вселенского масштаба. Нам всё приелось и сейчас уже мало что из новинок может порадовать, как тогда
RodionGork Автор
о да, Дельфи это фурор был :) не знаю почему VB6 на его фоне менее заметен был, он как будто даже удобнее был
а в 2011 году я устроился переписывать кучку разрозненных приложений с дельфи - на одно энтерпрайзовое джаванское - так исплевался от дельфи-то уже :)