Приветствую, Хабравчане!
Я сейчас добавляю возможность вывода изображений с помощью GDI и XLib. Но до конца код не готов. Но решил пока кода мало попробовать его собрать на нескольких старых компиляторах 30-ти летней давности. И только такой путь может дать нормальный бинарник работающий на системах Windows 98, 95.
Для загрузки графики использую stb_image. В итоге получилось так. Правда в оригинале цвет должен быть красным, а не синим. Но пока вывод изображений не закончен.
Основная репа RetroFan.
Картинка выводится с масштабированием GDI.

А, должен выглядеть так:

Для моих целей подойдет не каждый старый компилятор, а только с поддержкой namespace и каким то подобием поддержки шаблонов.
Со сцены сразу уходят Borland C++ компиляторы до версии 4.0
Решил начать с Visual C++ 4.0.
Всё это непотребство тестирую и компилирую на Windows XP установленную на VirtualBox 7.1.4. Я выбрал VirtualBox, потому, что он поддерживаете общие папки. Что позволяет предаваться ретро программированию с комфортом. Разрабатывая код на современных системах, в современном IDE.

Устанавливаем.

Что бы не привязываться к системе сборки от майков, вида nmake и создавать проект непосредственно в студии. Буду собирать простым bat файлом. Подаем ключи и файлы компилятору.
call "c:\msdev\bin\VCVARS32.BAT" cl /O2 -GX -FeLDL_Win.exe -I..\LDL\include ..\LDL_Win.cpp ..\LDL\source\*.cpp ..\LDL\source\Windows\*.cpp /link gdi32.lib winmm.lib user32.lib opengl32.lib cl /O2 -GX -FeLDL_Img.exe -I..\LDL\include ..\LDL_Img.cpp ..\LDL\source\*.cpp ..\LDL\source\Windows\*.cpp /link gdi32.lib winmm.lib user32.lib opengl32.lib pause
Ошибок конечно навалили:) Начнем разбираться.
Скрытый текст
Z:\make>call "c:\msdev\bin\VCVARS32.BAT" Usage: vcvars32 [target] Where target is one of the following: x86, m68k, mppc. No target specified. Selecting x86 as default target. Setting environment for building x86 target LDL_Win.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory BaseRndr.cpp ..\LDL\include\LDL/Color.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory BaseWin.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory Eventer.cpp ..\LDL\include\LDL/RngBuf.hpp(35) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/RngBuf.hpp(35) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/RngBuf.hpp(98) : error C2992: 'RingBuffer' : invalid or missing template parameter list ..\LDL\include\LDL/Events.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory GdiRndr.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory GdiTex.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory MainWin.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory Generating Code... LDL_Img.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory BaseRndr.cpp ..\LDL\include\LDL/Color.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory BaseWin.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory Eventer.cpp ..\LDL\include\LDL/RngBuf.hpp(35) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/RngBuf.hpp(35) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/RngBuf.hpp(98) : error C2992: 'RingBuffer' : invalid or missing template parameter list ..\LDL\include\LDL/Events.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory GdiRndr.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory GdiTex.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory MainWin.cpp ..\LDL\include\LDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list ..\LDL\include\LDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename' ..\LDL\include\LDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list ..\LDL\include\LDL/Vec2.hpp(52) : warning C4091: no symbols were declared ..\LDL\include\LDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<' ..\LDL\include\LDL/Vec2.hpp(52) : error C2059: syntax error : '<' ..\LDL\include\LDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
Быстрым гуглением по кодам и описанию ошибок, приходит понимание. Что ещё в до стандартные времена С++ каждый вендор понимал С++ по своему. Ошибка не сложная нужно просто заменить в объявлении шаблона typename на class.
syntax error : identifier 'typename'
Здесь уже сложнее, в поставку не входит STL и заголовки от С99. Тогда создадим их и передадим компилятору.
#ifndef LDL_Support_stdint_h #define LDL_Support_stdint_h typedef unsigned char uint8_t; typedef signed char int8_t; typedef unsigned short uint16_t; typedef signed short int16_t; typedef unsigned int uint32_t; typedef signed int int32_t; #endif
fatal error C1083: Cannot open include file: 'string': No such file or directory fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
На эту ошибку у меня ушло больше времени. Тип bool отсутствует, тогда я его добавил самым простым и очевидным способом.
typedef enum { false, true } bool;
error C2501: 'bool' : missing decl-specifiers
Но сработал другой способ. Переопределение через define. Правда теперь bool вместо 1-го байта, стал 4-ех байтным.
#if (_MSC_VER <= 1100) #define __forceinline #endif #if (_MSC_VER <= 1020) #include <Windows.h> #define bool BOOL #define true TRUE #define false FALSE #endif
Естественно компилятор 1995 года не знает ни о каких этих ваших интринсиках. Поэтому добавляем пару дефайнов, отключающие использование современных компиляторных фич.
..\stb_image.h(726) : fatal error C1083: Cannot open include file: 'emmintrin.h': No such file or directory
#if (_MSC_VER <= 1200) #define STBI_NO_THREAD_LOCALS #define STBI_NO_SIMD #endif #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"
Теперь все файлы собраны, на компиляторе 1995 года. Программы запускаются и работают корректно.
Z:\make>call "c:\msdev\bin\VCVARS32.BAT" Usage: vcvars32 [target] Where target is one of the following: x86, m68k, mppc. No target specified. Selecting x86 as default target. Setting environment for building x86 target LDL_Win.cpp BaseRndr.cpp BaseWin.cpp Eventer.cpp GdiRndr.cpp GdiTex.cpp MainWin.cpp Generating Code... Microsoft (R) 32-Bit Incremental Linker Version 3.00.5270 Copyright (C) Microsoft Corp 1992-1995. All rights reserved. /out:LDL_Win.exe gdi32.lib winmm.lib user32.lib opengl32.lib LDL_Win.obj BaseRndr.obj BaseWin.obj Eventer.obj GdiRndr.obj GdiTex.obj MainWin.obj LDL_Img.cpp BaseRndr.cpp BaseWin.cpp Eventer.cpp GdiRndr.cpp GdiTex.cpp MainWin.cpp Generating Code... Microsoft (R) 32-Bit Incremental Linker Version 3.00.5270 Copyright (C) Microsoft Corp 1992-1995. All rights reserved. /out:LDL_Img.exe gdi32.lib winmm.lib user32.lib opengl32.lib LDL_Img.obj BaseRndr.obj BaseWin.obj Eventer.obj GdiRndr.obj GdiTex.obj MainWin.obj
За кадром я протестировал версии Visual C++ 5.0 и 6.0 все собирается и больше никаких правок в код я не вносил.
Следующим шагом будут компиляторы от фирмы Borland. И ещё проверить Visual C++ 2.0, он поддерживает шаблоны и namespace. Тоже самое проделаю и со старыми Linux дистрибутивами, когда реализую вывод картинок на XLib.
В итоге, даже на таком древнем компиляторе можно использовать самописный STL и namespace. Что довольно хорошо. А самое главное, код совместим и с новыми компиляторами. Все несовместимости обернул в дефайны с проверкой версии.
Такими странными вещами я занимаюсь в свободное время:)
Буду рад предложениям, критике и советам. Уверен, есть куча компиляторов под Windows о которых я не знаю. Обязательно напишите их название, а я постараюсь собрать на них проект. К примеру узнал, что есть компилятор IBM VisualAge C++.
ссылка на оригинал статьи https://habr.com/ru/articles/876272/
Добавить комментарий