Игра с единорогом и алмазами для советского компьютера БК-0010-01
+123

Помимо непосредственно понных игр в стилистике MLP, довел до ума еще одну игру для старого компьютера БК-0010-01, на котором когда-то писал первые свои программы.
Героев MLP в игре нет, но есть единорог, а значит, отчасти соответствует тематике ресурса.
Проект также представляет интерес для любителей старых компьютеров и старых же игр.
Коротко о компьютере:
Оперативная память: 16 Кб
Видеорежим: 256x256 пикселей, 4 цвета.
Разрядность процессора: 16 бит
Система команд: совместима с PDP-11
Более полная информация:
Читать на Википедии
Сама игра простейший одноэкранный экшн, управляем лошадкой влево-вправо, ловим алмазы (за разные алмазы разные очки) и не попадаем под камни (на сложном уровне). Под катом скриншоты и ссылки на репозиторий/релизы игры.
Скриншоты:
Смотреть



А вот так выполняется на самом компьютере

Гитхаб проекта:
github.com/tereshenkovav/BK-0010-game
В файле README подробно расписана структура проекта и кода для тех, кого заинтересует древний ассемблер.
Поскольку этих компьютеров «на ходу» еще меньше, чем компьютеров на базе процессоров 386 и 486, я сразу же встроил эмулятор в дистрибутив игры для Windows:
Для 32-битной Windows:
github.com/tereshenkovav/BK-0010-game/releases/download/v0.9.0/PonyDiamonds-RU-0.9.0-BKEmulator-Win32.zip
Для 64-битной Windows:
github.com/tereshenkovav/BK-0010-game/releases/download/v0.9.0/PonyDiamonds-RU-0.9.0-BKEmulator-Win64.zip
В обоих случаях, после распаковки архива, нужно запускать файл run_game.bat и подождать загрузки главного меню игры.
На всякий случай, так же ссылка на чисто бинарный файл для выполнения на компьютере или эмуляторе:
github.com/tereshenkovav/BK-0010-game/releases/download/v0.9.0/PonyDiamonds-RU-0.9.0-BK0010.zip
278 комментариев
UPD — На ДВК мы играли в Star_Trek текстовую версию, где клингонцы были переведены как «шестижопы» ) Я её даже прощёл.
Дело хорошее, но… старая хотелка закрыта, теперь пора уже взрослые игры допиливать, люди ждут.
Если ошибка формирования объектных файлов — то надо подправить код под конкретный компилятор, или ключи нужные указать.
Если беда с линковкой, то надо найти библиотеки нужных версий и добавить к проекту.
Если сам exe падает после запуска — то скорее всего, не хватает каких-то dll или ресурсов.
Проблема, кажется, с линковкой… Я использую «CodeBlocks», так как разработчики сделали структуру проекта именно через него, если я правильно всё понимаю! При запуске рабочего пространства он настойчиво просит указать то, что нужно библиотекам. Я делаю это, но, при компилировании «GUIMultiplayerLoginScreenFunctions.cc», VS Code ругается на отсутствие файла «Definitions.h» (хотя, что мне кажется смешным — то, что он сам видит его и даже открывает. Чушь какая-то...); CodeBlocks заходит дальше — компилирует этот злосчастный файл, но ругается на отсутствие «Allegro5/Allegro.h». Я пытался делать все: и прикрепил его во вкладки «Linker» и «Compiler», и указал флажки(правда, судя по всему, они как-то навязаны для Линукса?), и всё такое, но, к сожалению, почему-то оно не хочет комплиироваться. Эх…
По совету английских товарищей из интернета, поискал старый аллегро и… Не нашёл. :D
Рано или поздно либо я, либо makise_homura победят лень и сообразят для исходников пакетник или CMakeLists.txt
Надеюсь, это вам чуть сможет помочь!
Справедливости ради, у меня тоже с этим не очень, если для Windows я все либы кладу в каталог проектов, то для Linux и MacOS нужно бы добавлять проверки на корректность системной версии.
Я… Не могу просто закинуть DLL? Всё прямо так, как я предполагал...
— О, горе мне, горе…
В общем, если разработчики не подготовили систему сборки, то придется самому становиться разработчиком.
Да, не зря разработчики порой хаили друг друга в код, посредством комментариев. :D
В C# библиотека — это и есть dll, то есть метаданные читаются напрямую с бинарника.
В C и Паскале — заголовочный файл может быть один, а бинарный файл другой, и начинается веселье.
Всё еще самый безопасный способ, крупный минус только один — распухание дерева исходников и, отчасти, затруднение с переходом на новую версию библиотеки (последнее уже не сборка, а полноценная разработка, и не может быть простой).
Хорошо, пусть; а если вдруг потребовалась статическая линковка, то что? Как функции с __dllexport можно будет статически прилинковать?Самый крупный минус — это невозможность собрать с использованием другого ABI и тем более на другой архитектуре.
Да, так устроен .NET
Статическая линковка не предусмотрена, зато ты можешь одной командой сформировать каталог со всеми dll и забрать его с собой.
Блин, недавно у меня тут на телефоне сбербанк-онлайн обновился, честно, я не представляю, какого хрена тот функционал, что можно было уместить в 30 кБ, весит 260 МБ, да ещё и тормозит лютейшим образом.
Можно, умести.
Обычный же вектор прогресса — от нативных ассемблеров к универсальным компиляторам.
Желающих писать на ассемблере не стало, как только появилась возможность скомпилировать Console.WriteLine() под десяток платформ разом, и там же запустить.
Со сбербанком, кстати, то же самое — хакерский код на 32Кб для клиента банка будет крут, но и поддерживать его сможет тот самый единственный хакер, а это плохо. Потому правят фреймворки и готовые решения, которыми сможет заниматься человек после недели курсов.
Отдать продукт качественный через год, или выпустить плохонький, но через месяц? Ответ очевиден.
Сейчас оплачивая билет в трамвае картой или проездным, ты запускаешь цепочку из сотни сервисов, каждый из которых нуждается в разработке и доработке. Но желающих платить монетами уже не осталось.
Если работать строго по прямому назначению кода, то будет карта, работающая в конкретном трамвае конкретного города конкретного депо. Без шансов подключить что-то еще.
Отсюда и разбивка на сотни сервисов, и независимые куски, и старые подсистемы, которые лет 50 работают, но трогать их нельзя.
Использовать существующие сервисы платёжной системы с миллионами пользователей, вместо того, чтобы накидать свой вариант попроще — это обоснованное усложнение, которое действительно даёт привычность и универсальность.
Делать ридер карт не на атмеге с обвесом, а на атоме с PCIe-картой-контроллером RS-485, к которой приделан ридер из тех, что применяются на производствах и стоят не 2$, а 200$, просто потому, что программист не умеет писать для ардуины, зато умеет делать bloatware для винды (поэтому загрузка терминала длится 2 минуты, а не 2 секунды) и писал код только для такого ридера, но не для других — это переусложнение, и от него стоит избавляться.
А это уже следствие того, что люди стоят дороже, чем железо.
Ты пойди найди еще программиста для ATMega — я к примеру, теорию знаю, но написать что-то сложнее моргающего светодиода так не смогу. И кому будет радость от твоей атмеги, если софт для неё не напишут, или напишут за сотни нефти?
Изменить это можно только одним способом — уменьшить оплату за труд разработчика до МРОТ,
расстрелятьзакрыть всех айтишных ИП-шников и жестко попячить все частные конторы разработки, а также принудительно отправлять людей на конкретную задачу — «вот ты, Васян, пишешь карт ридер для атмеги, а ты, Колян, к нему собственный протокол».Не уверен, что этот мир будет лучше, чем картридер на WinCE.
Вряд ли. Плюс всё еще нужны специальные знания — программист под Windows может не знать слова «пин, вольт, логический уровень, прижимание к земле», а для МК это нужно, хотя и меньше, чем для распайки оного.
Сейчас для тех же целей нужен огромный сервер и огромная инфраструктура, да еще никто не доверит это все в одно рыло, слабозаменяемое и возможно, капризное рыло.
Но никто так делать не будет, потому что плохонький уже есть, развитие не нужно, а народ пусть жрёт что дают, альтернативы ж нет.
Для того, чтобы продукт покупали, нужно к нему постоянно делать новые плюшки. А если вместо плюшек делать рефакторинг, то народ купит версию 2.0 уже у соседней конторы, потому что её продукт хоть и жрет в два раза больше ОЗУ, но зато умеет еще пару новых функций.
И ни один инвестор или учредитель не позволит 11 месяцев просто так тратить на улучшение кодовой базы без видимого результата. "- Мужики, мы сократили дублирование кода в три раза и повысили скорость рендера на 20%! — Молодцы, все уволены к хренам."
Для банка его приложение не является основной деятельностью, оно запущено по принципу «штоб былО»
Работа банка — это кредиты, залоги, вклады, операционная деятельность. Хорошо, что вообще какое-то приложение есть и какой-то сайт.
Правда, у первого тоже есть некоторые «находки», но так как они исходно без отделений были, то косяки сайта чинят быстро, и обслуживают по телефону лучше. Не реклама, но рекомендую.
… потом забывает добавить контрольную сумму для счета, перевод на 9999999 рублей уходит в содержимое неинициализированной памяти и к банку едет недовольный клиент в сопровождении СОБРа или ОМОН, пояснять за надежность софта :-)
Утрирую чуток, но банковский софт — это не игры с понями скачущими, это на три порядка серьезней.
«А мужики-то не знают»©
Мы как-то делали примитивный эквивалент для внутреннего учета — там тоже были
причем даже не касаясь переводов внешних.
Через три месяца всех разогнали и за сотни нефти купили готовое решение.
Потому что денежные операции (даже виртуальные) — это ПЦ как сложно.
Но нормальное обеспечение безопасности — это OpenSSL и доверенные протоколы, а не сотни мегабайт неиспользуемого кода фреймворков и попытки втюхать пользователю, что ему «звонил мошенник» каждые 15 минут (даже если никто не звонил вообще).
Это как нынешняя мода на приложения на Electron-е: 10 кБ кода и сотни мегабайт встроенный браузер, в котором этот код выполняется.
Пару раз мне встречались концепции, дескать, Дельфи такой тяжелый, а у меня приложение на C++ WinAPI в 50 раз меньше, давайте на нём делать. Давайте. Но когда число компонентов вырастало за сотню, а обмен данными шел в три стороны — все тут же вспомнили, как классно было жить на событиях, VCL и ProcessMessages()
Структура библиотеки VCL одна из лучших, на уровне Qt для своего времени и выше уровня всяких Gtk и WinForms
Delphi позволяет прозрачно использовать вызовы WinAPI, лучше него это делает только C++. Вплоть до того, что можно делать оконное приложение на ObjectPascal без VCL. То есть, если хочешь бахнуть уникальный компонент — можешь прямо гнать чистый Win-код с привязкой чего угодно.
Другое дело, что за 30 лет уже все-все-все компоненты написаны и нужда в собственных — это редкость.
1) Разработчики фреймворков в целом более квалифицированные люди, и делают это лучше.
2) Многие моменты, которые не видны при разработке, становятся видны при запуске у клиента (привет, настройки DPI), промышленный фреймворк это учел, самодельный фреймворк — как повезет.
3) При обновлении программы, нужно обновлять и фреймворк, и программы. Промышленный движок обновляют за тебя.
4) (важно, если работаешь не один или пишешь заказчику с передачей кода) Тому, кто будет поддерживать/дорабатывать твой код, придется выучить твой фреймворк, что сводит число кандидатов на замену практически в ноль. Быть привязанным к своему проекту чугунными цепями — это плохо.
2) — Ну, тем разработчикам эти моменты тоже не через libastral снизошли) Вдумчиво курить маны, нормальную литературу (а не книжки «я у мамы программист за 21 день»), те же исходники других фреймворков, и прочее. На самом деле практически все типовые грабли (тот же DPI) давно описаны, надо только не лениться инфу искать.
3) Так если это твой фреймворк — что мешает?) Наоборот, кто как не ты, лучше всего знает что может вылезти при обнвлении, когда все компоненты твои.
4) Спорно. Так и так им придется чужой код курить, а хорошо спроектированный фреймворк наоборот внесет архитектурную ясность.
заказчик уйдет к другому исполнителю, который попроще, но взял готовый VCL/Qt/WinForms и выдал результат за два дня, а не за две недели.
По пункту 4, опять же, новый исполнитель не захочет тратить время на изучение фреймворка, который только тут и используется — и заказчик будет огорчен. А огорченный заказчик это плохо, а если он некультурный, то еще и больно.
А тут вообще ситуация странноватая. Заказчику нужна решенная задача. Исходник его вообще волновать не должен, хоть он на фортран-66 сделан. Если же хочет взять исходник и ковыряться сам — ну так проблемы индейцев шерифа не волнуют уже.
2) Вот только всё предусмотреть достаточно сложно — опять же из-за пункта 1.
3) Мешает необходимость уделения этому большего количества времени?
Вот я уже понял, что писать свой консольный «фреймворк» для RUMIA было плохой идеей, потому что из первоначальной идеи «лазить на парочку компов по ssh и смотреть температуры» это превратилось в огромного слабоподдерживаемого крокодила, и это надо теперь активно переводить на ncurses хотя бы.
4) Вот только не всегда «хорошо спроектированный фреймворк» — это твой, а не общеиспользуемый))
2) Опять же, свой узкозаточенный фреймворк проще в поддержке, чем монстр типа Qt. Сотня QA там просто не нужна.
3)-4) Тут по ситуации. Да, если фреймворк вырастает спонтанно из *первоначальной идеи «лазить на парочку компов по ssh*, там по итогу может оказаться слабоподдерживаемый клубок кода, знакомо. Поэтому опять же — проектировани и архитектура наше все.
Программирование на заказ с передачей исходников или для компании — только массовые языки и только популярные фреймворки. Любой велосипед тебя высечет, рано или поздно.
И даже его знает больше людей, чем твой самодельный фреймворк.
Ну под свои задачи и нет смысла писать свой Qt с блекждеком и Рэрити) Фреймворк вполне может быть легковесным, как тот же FLTK например.
НО: по нему море документации и океан примеров.
И тысячи спецов.
wxWidgets более-менее еще.
Меня больше сейчас огорчает отсутствие промышленного компилятора Бейсика, хотя бы уровня FreePascal.
Есть FreeBasic, но он слабее того же FreePascal.
(вот в линуксах всё из коробки, лол, при этом шланг что поставленный из реп, что собранный с нуля — работает идеально, ну, как минимум у меня).А на бейсике в 2023 ещё что-то пишут?))
(няз, были какие-то конверторы из традиционного бейсика на си и на питон, что ли, кажется, вполне норм решение)
Мир не ограничивается С++
VCL так и работает, чтобы убить дельфийское приложение, нужно очень постараться, и тебе в любом случае кинут хотя бы AccessViolation с адресом.
Например, следующий пример на C# будет обработано корректно с понятным исключением.
а вот на Паскале или Си такой пример убивает программу, что конечно, сильно мешает работе.
safeTrim(s)
в которой типа
if (s=nil) then raise TException.Create('все плохо') else s.Trim();
а C# это делает сам и везде.
Скорее тебе надо перегрузить конструктор, чтобы он прежде всего позволил тебе создать строку из nullptr, а не кидал исключение std::logic_error c чем-то типа «basic_string::_M_construct null not valid».
class my_string_t { public: my_string_t() = default; my_string_t( const char* s ) { if( s ) { memcpy( (p = new char[len]), s, (len = strlen(s)) ); is_null = false; } } ~my_string_t() { if( !is_null ) delete[] p; } private: char* p = "дядя, тут нулл"; size_t len = 0; bool is_null = true; };нормальные языкиязыки кроме паскаля?))))Тебе либо надо писать такую функцию в принципе (потому что в стандартной библиотеке нет trim() и тогда то, как ты будешь обрабатывать ситуацию src == NULL, лежит на твоих плечах), либо у тебя нет способа необрабатываемым образом без извращений загнать nullptr в std::string или его аналог.
То, что при подаче на printf("%d") выведет 0.
Ситуацию, когда по указателю находится мусор, конечно, не рассматриваю.
TPony * createPony(string code)
{
if (code==«pegas») return new TPegas();
if (code==«unicorn») return new TUnicorn();
}
а про земных пони забыли, и если я сделаю так:
auto pony = createPony(«earth»);
pony->Run()
то системы вроде C# и .NET дадут мне внятный ответ, что случилось
А программа на C++ просто рухнет, ничего не сказав на прощание.
{
if (code==«pegas») return new TPegas();
else if (code==«unicorn») return new TUnicorn();
else throw std::logic_error(«странная зверюшка»);
}
то есть в дереве условий всегда делать последнюю ветку с эксцепшеном. А если ветвей много, то лучше в сторону std::map посмотреть или типа того.
Но я согласен, что это противоречит идее С и С++. Там минимум проверок, максимум скорости. Потому что задачи другие решаются. Бизнес-логику на 100 классов никто на плюсах делать не будет, а если будет, то пожалеет.
безблагодатность))) Управление памятью — это часть более общей проблемы управления обобщенными ресурсами. Допустим да — при выделении памяти можно принять что 0 это ошибка, и отслеживать рантаймом (экзотические архитектуры и МК допустим не рассматриваем). Но существует куча хэндлов, для которых ноль — вполне валидное значение. У сокетов например неверное значнеие это минус единица. У файлов в линухе ноль — вполне себе хэндл. И так далее — огромная куча вариантов. С этим как быть, если пихать все в дефолтный рантайм. Поэтому и отдано на откуп кодеру, чтобы делал безопасные обертки по ситуации.Для простых типов — по-другому.
В C# просто решили, что всё есть объект (даже int) и они различаются только обработкой и передачей (по ссылке для одних классов, по значению или копированию для других).
И да, записать в C# MyClass a = 0 не выйдет, если только MyClass не определен как целочисленный.
Цена этого всего, конечно, огромна, по памяти и размерам фреймворка.
Для обычных объектов логики такого не требуется.
Смысл сборщика в том, что в крупных проектах не всегда возможно удалить объект там же, где его создал — потому что создают как правило фабрики, а удаляются по устранению в нём надобности. И всё попытки отказаться от сборщика мусора (которые в том или ином виде существуют во всех языках, даже в ObjectPascal с его IInterface и счетчиком ссылок) — приводили к тому, что в программе появлялся собственный велосипедный сборщик мусора, разве что написанный не инженерами Microsoft/Sun, а автором проги :-)
Или я тебя не понял, или ты сейчас пытаешься починить то, что не сломано.Как бы в С++ тоже (но там важна не целочисленность, а наличие конструктора по подходящему аргументу).
Так что в случае с TPony там никакой проверки на nullptr не нужно, потому что nullptr вообще не фигурирует в коде. А если ты по умолчанию возвращаешь nullptr — то ты ССЗБ, потому что не знаю как тебе, а мне выглядит намного более логичным вариантом возвращать неспецифицированный объект (т.е. базового класса) вместо какого-то непонятно откуда взятого nullptr.
А во-вторых — зачем проверять рантаймом, если это намного логичнее сделать на этапе сборки?
Да нет, не пожалеет — посмотри тот же CMake, там классов пару сотен, и всё более-менее понятно.
Это кстати, отдельная проблема, что компилятор позволяет в объявленной переменной находиться мусору, вместо того, что по умолчанию поставить туда дефолтное значение типа.
Но да, для С++ это недопустимо, ибо скорость и размер кода.
Ты сейчас пытаешься, как я понимаю, реализовать фабрику, а значит, тебе достаточно в фабричной функции просто по дефолту возвращать объект базового класса, а в базовом классе сделать виртуальный метод, кидающий эксепшен. Вот так:
#include <iostream> class TPony { public: virtual void Run() { throw std::logic_error("I don't know who I am"); } }; class TPegasus: public TPony { public: void Run() { std::cout << "I can fly" << std::endl; } }; class TUnicorn: public TPony { public: void Run() { std::cout << "I can do magic" << std::endl; } }; TPony* createPony(std::string code) { if (code=="pegasus") return new TPegasus(); if (code=="unicorn") return new TUnicorn(); #if RIGHT_VERSION return new TPony(); #endif } int main() { auto rainbowDash = createPony("pegasus"); auto twilightSparkle = createPony("unicorn"); auto applejack = createPony("earth"); rainbowDash->Run(); twilightSparkle->Run(); applejack->Run(); }В твоей реализации (случай RIGHT_VERSION == 0) компилятор сразу кинет тебе -Wreturn-type, с чего ты поймёшь, где и почему ты лажанул, ещё при компиляции, а не когда словишь сегфолт:homura@reisen ~ $ c++ -DRIGHT_VERSION=0 factory_test.cxx -o factory_test && ./factory_test factory_test.cxx: In function ‘TPony* createPony(std::string)’: factory_test.cxx:28:1: warning: control reaches end of non-void function [-Wreturn-type] 28 | } | ^ I can fly I can do magic Ошибка сегментирования homura@reisen ~ $В то время, как при нормальной реализации, когда ты так сделал, всё получается нормально (как говорил профессор Фортран, нормально делай — нормально будет):А вообще, если ты значение `code` получаешь не откуда-нибудь, а пишешь прямо в коде, то тут легче вообще шаблоны использовать — тогда тебе будет очень легко расширить твой код, когда ты решишь добавить земных, аликорнов, и всё такое.И в этом случае им тот же C# поможет — частично паттерн нулевого объекта реализован самой библиотекой рантайма.
А на С++, к слову, няз, вообще нельзя создать std::string из nullptr.
Я про С++ больше.
По nullptr — могу же присвоить, ну пусть такой код
MyClass * var = NULL;
var->MyMethod();
PS: Ах да, сорок тысяч видов null в С/С++, против nil у Pascal, NULL у C# и 0 у Бейсика.
Так и не смог запомнить, когда какой применять.
В грамотной архитектуре такого не будет. Но если параноить, то навскидку
#define SAFE_CALL( var, ... ) do { if( (var) ) { (var)->__VA_ARGS__; } } while(false) и вызываем SAFE_CALL( var, MyMethod() );можно и через шаблонную магию — parameter pack и std::forward, но чутка побольше писанины будет в безопасной затычке.
nullptr всегда и везде. Все остальное древность для лютого леагси.
Чем сложнее программа, тем выше шанс, что где-то не инициализировали.
Уже при динамическом создании данных (например, маппинг из базы или конфига) это всё превращается в тыкву и нет никаких способов убедиться, что в поле pony лежит класс единорого, пегаса или просто null
И тут на сцену выходят умные языки, которые помогают хотя бы понять, что случилось.
Понимаешь, каждый раз, когда ты пишешь `Something *p = nullptr;`, ты должен задавать себе вопрос, а зачем ты так делаешь, и чем это лучше а) `Something *p = new basicSomething;` или б) `Something *p;`.
Почему тогда код
int * x = 0;
будет откомпилирован?
В Паскале, например, это тип Object, который уже не собрать ни Delphi, ни FPC без специального ключа. Хочешь работать с Object, ставь TurboPascal. Или перейди на TObject, который современный.
В C++ такие конструкции — это вероятно, использование new/delete, указатели по звездочками и прочие трюки из ранних 80-х. И свежие версии gcc их поддерживать не должны, без явного указания стандарта.
Если в системе создаются тысячи объектов в минуту (обычное дело для высокой нагрузки базы или сайта) — то такое «возьму» заканчивается всегда одинаково, уходом сервера в перезагрузку.
(да, примерно поэтому тот же фаерфокс только жрёт и жрёт память, но никогда её не освобождает =)
С GC дело иное — вызов new говорит системе «братан, я тут у тебя немного памяти возьму, а вернет её тебе мой шеф, 100% вернет, рано или поздно».
Firefox скорее всего написан аккуратно, а память жрут сложные скрипты на сайтах (по сути, Firefox — это ОС, а сайты — прикладные программы).
Ну так вот эти скрипты и написаны на JS, в котором есть GC. И потому, пока вкладку принудительно не закроешь, память ты обратно не получишь обычно(
Но это и другие задачи, конечно — либо пишем с нуля, либо берем узкоспециальные движки.
Qt? Но да, у неё порог входа выше и стоит, емнип, 5000$ в год для полноценной лицензии на коммерцию с закрытыми сорцами.
Эм, нет. Qt5 прекрасно работает. Qt6 — да, уже никак, но это нормально. Как большинство компиляторов и библиотек уже не поддерживают WinXP, так и Win7 перестают. Сейчас основная версия — это Win10.
А компиляция таки настраивается, прямо по инструкции от самой МС.
learn.microsoft.com/ru-ru/cpp/build/configuring-programs-for-windows-xp?view=msvc-170
Чутка потрахаться — ну то ж стиль МС, все автогеном через жопу делать)
фактически, нужно собирать runtime руками.
Уже и семерка-то осталась у единичных машин.
Хотя я тоже свои проекты под семеркой тестирую в обязательном порядке, но это уже скорее перестраховка. Никто под семеркой ничего моего не запустит.
Просто отмечу, что семерка — это 2009-ый год, это прошло уже 15 лет, два-три цикла смены технологий.
неотключаемые обновления и телеметрия везде и всюду. и с nvme ssd она по слухам паршиво работает
Firefox прекрасно обновляет свои сертификаты, это даже не надо делать руками, всё автоматизировано и незаметно для пользователя.
Ну я-то осилил, правда, каждый раз это великие жертвы всем богам экспорта и импорта сертификатов в доверенное хранилище. Но обычный пользователь на этом этапе уже встанет в неприличную позу, особенно если использует Chrome вместо FF
Проверю.
То есть явно видо, что над сетевой частью разрабы дискорда совершенно не задумывались, лепили что получится — но тем не менее, даже у него проблем с сертификатами никаких.
Вот стим выкинул подлянку, но я туда ходила-то пару раз в год. Но видимо придётся поставить десятку :\Простите, несдержалась…
Всё, что есть — это серверные технологии, для использования которых локально сперва надо накатить подходящий под данное конкретное оборудование набор фреймворков и библиотек гигабайта этак на полтора суммарным весом.
И вот как только нужно, чтобы нейронка крутилась не на сервере, куда клиенты только отправляют запросы, а поставлялась пользователям в виде бинарника и работала локально на любом GPU (NVidia, AMD, Intel) или даже без оного (расчёты на CPU), то оказывается, что вменяемых альтернатив-то и нет.
Electron работает везде, даже на мобильных устройствах, код один и тот же. Оно само выбирает, то ли компилировать wasm и считать на CPU, то ли создавать и компилировать шейдера на WebGL и юзать GPU.
почему невозможно? Удаляем файлы 32-битной версии SFML из каталога addons/SFML, копируем туда 64-битный SFML, компилируем.
Чуть сложнее, чем просто сменить указание цели в CMake, но первичная-то задача — обеспечить без лишних движений сборку на исходной архитектуре, а если человек хочет поменять, это уже его дело и его хлопоты.
Обрати внимание, что для Linux и Mac я так не делаю, к примеру — там понятно, что .h и .so должны идти из системных каталогов.
Он позволяет под Windows загрузить с указанного URL хедеры и библиотеки? Если так, то это хорошие новости, буду пробовать.
Это довольная серьезная проблема, например, для проектов на .NET — там всё завязано на сервера nuget, и без создания собственной копии — каждый раз думаешь, позволят тебе пакеты скачать, или отрубят, потому что ты был плохим мальчиком этот год.
Я тестировал даже на виртуалках, и везде игра стартовала, пусть и тормозила чудовищно.
Но так-то да, всех исключительных ситуаций не предусмотришь.
Некоторые умельцы под оригинальный терминальный PDP-11 делают игры и вот это уже реально круто.
github.com/smaslovski/ponydiamonds
Вдруг кто-то из старичков захочет сам собрать, а под Linux с make-скриптом немного проще.
Ништяк)
Для популярных эмуляторов типа DOSBox — список несовместимых вещей укладывается в пальцы на руке, там всё очень хорошо отлажено за годы.
БК более редкий зверь, но топовые эмуляторы к нему совместимы тоже на 99.9%, расхождение находятся очень редко и как правило, связаны с багами конкретного БК (вроде выпиленного на заводе таймера) или трюками типа «давайте вручную модифицируем регистр-указатель на код и поставим ему нечетное значение».
Как и для железа под DOS. У меня есть материнка, на которой отправка chr(7) в консоль вместо радующего звука — вещает систему.
Ну вот не звучит там DOOM так, как звучал во времена моего детства(
Да, вот я именно про такое: из-за этого часть демок, особенно уровня 4k competition или 512b competition на эмуляторах не работают(