Приветствую, читатели!
Я сейчас добавляю возможность вывода изображений с помощью 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:msdevbinVCVARS32.BAT"
cl /O2 -GX -FeLDL_Win.exe -I..LDLinclude ..LDL_Win.cpp ..LDLsource*.cpp ..LDLsourceWindows*.cpp /link gdi32.lib winmm.lib user32.lib opengl32.lib
cl /O2 -GX -FeLDL_Img.exe -I..LDLinclude ..LDL_Img.cpp ..LDLsource*.cpp ..LDLsourceWindows*.cpp /link gdi32.lib winmm.lib user32.lib opengl32.lib
pause
Ошибок конечно навалили:) Начнем разбираться.
Скрытый текст
Z:make>call "c:msdevbinVCVARS32.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
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
BaseRndr.cpp
..LDLincludeLDL/Color.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
BaseWin.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
Eventer.cpp
..LDLincludeLDL/RngBuf.hpp(35) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/RngBuf.hpp(35) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/RngBuf.hpp(98) : error C2992: 'RingBuffer' : invalid or missing template parameter list
..LDLincludeLDL/Events.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
GdiRndr.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
GdiTex.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
MainWin.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
Generating Code...
LDL_Img.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
BaseRndr.cpp
..LDLincludeLDL/Color.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
BaseWin.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
Eventer.cpp
..LDLincludeLDL/RngBuf.hpp(35) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/RngBuf.hpp(35) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/RngBuf.hpp(98) : error C2992: 'RingBuffer' : invalid or missing template parameter list
..LDLincludeLDL/Events.hpp(30) : fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory
GdiRndr.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
GdiTex.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/BaseWin.hpp(31) : fatal error C1083: Cannot open include file: 'string': No such file or directory
MainWin.cpp
..LDLincludeLDL/Vec2.hpp(32) : error C2952: template declaration must specify parameter list
..LDLincludeLDL/Vec2.hpp(32) : error C2061: syntax error : identifier 'typename'
..LDLincludeLDL/Vec2.hpp(50) : error C2992: 'Vec2' : invalid or missing template parameter list
..LDLincludeLDL/Vec2.hpp(52) : warning C4091: no symbols were declared
..LDLincludeLDL/Vec2.hpp(52) : error C2143: syntax error : missing ';' before '<'
..LDLincludeLDL/Vec2.hpp(52) : error C2059: syntax error : '<'
..LDLincludeLDL/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:msdevbinVCVARS32.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++.
Автор: JordanCpp