Приветствую, Хабравчане!

Я сейчас добавляю возможность вывода изображений с помощью 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++.

Комментарии (33)


  1. unreal_undead2
    24.01.2025 09:24

    Comeau славился хорошей поддержкой 98го стандарта (включая export), должен справиться (если удастся его найти). Topspeed ещё в своё время был на слуху, но боюсь туда новомодные namespace/template не доехали.


    1. JordanCpp Автор
      24.01.2025 09:24

      Спасибо, посмотрю.


  1. NickDoom
    24.01.2025 09:24

    Мне кажется, для легасей ничего лучше опенваткома не придумали ещё :)

    Но может и казаться, конечно…

    UPD: что-то охота поиграться с VGA для какого-нибудь элементарного рендерера типа Wolf3D. С нормальной пушкой — 320х200, а взял ночной снайперский прицел — включается 640х480, где рендерятся все 4 цветовые плоскости по очереди :) Такая цепочка «призраков» от прошлых кадров, типа это так ночная оптоэлектроника работает :) И 16 цветов, конечно, раз VGA 640x480. Может быть прикольно :)

    Короче, меня тоже пробило на олдскул %)


    1. JordanCpp Автор
      24.01.2025 09:24

      Да это отличный компилятор. И мне нравится, что он может кросс компилировать под старые ОС. Но мне ещё интересен момент нативной сборки на устаревших ОС.

      Мне это позволяет посмотреть и пощупать старые ОС, компиляторы и т.д


    1. JordanCpp Автор
      24.01.2025 09:24

      Я после gdi и xlib буду встраивать рендер в буфер, как это раньше делали с поддержкой палитры.

      Короче, меня тоже пробило на олдскул %)

      :)


    1. unreal_undead2
      24.01.2025 09:24

      Если под DOS - так можно и достаточно свежий gcc взять.


      1. JordanCpp Автор
        24.01.2025 09:24

        Интересно надо будет посмотреть. С дос пойду таким же нативным путем. У в проекте все имена сорцов длиной 8 символов. Что бы нативно все собирать под dos и windows 3.1

        В идеале собирать под максимальное количество компиляторов. Зачем? По фану:)


        1. unreal_undead2
          24.01.2025 09:24

          Тогда как вариант ещё попробовать CodeWarrior под MacOS 9.x и BeOS )


          1. JordanCpp Автор
            24.01.2025 09:24

            Да, хотелось перенести под множество систем. К примеру рендер основанный на буфере, можно и под микроконтроллеры портировать.


  1. Siemargl
    24.01.2025 09:24

    Надо брать последний компилятор под платформу. Согласно СО для VC это версия 2003, кстати была и бесплатная. Чтобы получше поддержка стандарта была.

    Ну а так еще Ватком, мингв, симантек (dmc), борланд поновее, остальное совсем экзотика

    Stl шла от dinkumware


    1. LAutour
      24.01.2025 09:24

      VC2003 - это там где сервис пак на студию ставился очень-очень-очень долго по сравнению с установкой самой студии?


      1. Siemargl
        24.01.2025 09:24

        Microsoft Visual C++ Toolkit 2003 если точно, 31Мб, SDK 6.0 качать отдельно


    1. JordanCpp Автор
      24.01.2025 09:24

      Сейчас проект собирается на следующих компиляторах, для компиляторов без STL я добавил свою реализацию std::string и stdint.h

      Visual C++ 4.0

      Visual C++ 5.0

      Visual C++ 6.0

      Собираю последней версией msvc 2022 и на linux gcc 13.

      Всё, что выше Visual C++ 4.0 соберет, просто нужно протестировать. К примеру до версии MSVC 2010-2013 отсутствует stdint.h, его просто нужно добавить в пути сборки и должно все собраться. Для этого создал каталог support.


      1. emusic
        24.01.2025 09:24

        В чем смысл затачивания кода под старые компиляторы? Какова вероятность, что кому-то потребуется собирать его именно ими?

        Если что, VC++ вплоть до 6.0 не понимает многих библиотек из MS SDK (там новый формат).

        Так-то нет никаких проблем собирать PE хоть под Win95 самыми последними версиями VC++.


        1. JordanCpp Автор
          24.01.2025 09:24

          В чем смысл затачивания кода под старые компиляторы?

          Мне интересно собрать код нативно. Поставить старую ос, туда компилятор той старой версии, собрать проект.

          К примеру ещё это позволит собирать проект из коробки на старых версиях Linux с поддержкой gcc >= 2.95, а может ещё и более древней версией компилятора.

          Это большой плюс для тестирования производительности с тем оригинальным железом.

          Я бы не сказал, что я прям затачиваю код под старые компиляторы. Код С++ 98 с STL и namespace. Куда уж стандартней Правда без новых фич, зато не отвлекают:)

          Так-то нет никаких проблем собирать PE хоть под Win95 самыми последними версиями VC++.

          Это как? Я как раз использую visual c++ 6.0 именно потому, что бинарник может работать под windows 9x.


          1. emusic
            24.01.2025 09:24

            собирать проект из коробки на старых версиях Linux с поддержкой gcc >= 2.95

            С линуксами, где компилятор идет в составе ОС, как раз понятно. Непонятно с виндами, где под любой версией можно использовать [почти] любой компилятор.

            Я как раз использую visual c++ 6.0 именно потому, что бинарник может работать под windows 9x

            Коли уж Вы во все это полезли, стоило бы в общих чертах разобраться со структурой PE и особенностями средств сборки. :)

            Система вообще ничего не знает о том, каким компилятором/линкером собирался PE - она тупо смотрит на его заголовок и таблицы, чтобы определить, сможет ли она его загрузить. В этом смысле компилятор вообще не имеет значения - только линкер.

            Если значимые характеристики PE (платформа, подсистема, параметры секций, необходимые импорты и прочее) ее устраивают, то единственное, что может помешать загрузке - это номера версий системы/подсистемы, а их можно установить произвольно. Самые новые компиляторы не позволяют устанавливать номера ниже 5.1 или 5.0, но ничто не мешает использовать сторонние утилиты для правки версий уже после сборки.


            1. JordanCpp Автор
              24.01.2025 09:24

              Коли уж Вы во все это полезли, стоило бы в общих чертах разобраться со структурой PE и особенностями средств сборки. :)

              Я исходил из практических целей простоты. Где не нужно, что то нестандартное колхозить. Пишем код на С++ 98, берём совместимый компилятор. Собираем и работает.

              Я не спорю что можно собрать на последней версии msvc в асм. Прогнать через, какую нить прогу, которая создат асм совместимый с fasm бородатой версии и собрать уже на нативной системе.

              Я исходил из простоты. Пока данный метод не подвёл.


              1. emusic
                24.01.2025 09:24

                можно собрать на последней версии msvc в асм

                Не нужен никакой "асм". Компилируете cl.exe, собираете link.exe, больше ничего не требуется, кроме [возможной] правки номеров версий в заголовке полученного PE.


            1. JordanCpp Автор
              24.01.2025 09:24

              Мне ещё кидали ссылку на патч для современной версии gcc, собирающейся и работающей на windows 98. Без потоков, но остальные фичи доступны. Но я пока не готов в этом разбираться, слишком временно затратно получается.


              1. emusic
                24.01.2025 09:24

                Ну, если от libc нужна поддержка системно-зависимых функций (национальные алфавиты/единицы, работа с памятью, файлами и прочее), то совместимость довольно быстро падает с ростом количества затребованных функций.


                1. JordanCpp Автор
                  24.01.2025 09:24

                  Библиотека LDL будет ограничена единым кроссплатформенным API для графики. Все остальное, забота разработчика.


        1. JordanCpp Автор
          24.01.2025 09:24

          В будущем хотелось бы портировать на старые консоли и другое вообще железо. Там компилятор не обновлялся десятки лет.


          1. emusic
            24.01.2025 09:24

            Тогда имеет смысл начать с Windows CE/Mobile. :)


            1. JordanCpp Автор
              24.01.2025 09:24

              В том числе, да.


        1. JordanCpp Автор
          24.01.2025 09:24

          Если что, VC++ вплоть до 6.0 не понимает многих библиотек из MS SDK (там новый формат).

          О каких именно библиотеках речь?


          1. emusic
            24.01.2025 09:24

            Сейчас уже не вспомню, но это было причиной моего перехода с 6.0 на 2005 (а может вру, и это было с 4.2 на 6.0). Я отчаянно не хотел перелезать, но линкер не понимал некоторых .lib из новых SDK/DDK, а колхозить конвертор и преобразовывать вручную тоже не хотелось.


        1. Siemargl
          24.01.2025 09:24

          Так-то нет никаких проблем собирать PE хоть под Win95 самыми последними версиями VC++.

          Вообще то нет. Есть стартуп код, да и стандартные библиотеки зачастую новые системные вызовы используют


          1. emusic
            24.01.2025 09:24

            Все это относится к категории "таблицы PE" - что компилятор затребует (явно или неявно), то линкер туда и положит. Если стартовый код свой и использование libc ограничено разумным набором общих функций, то совместимость хоть с Win95 достигается элементарно.


  1. da-nie
    24.01.2025 09:24

    Правда в оригинале цвет должен быть красным, а не синим. Но пока вывод изображений не закончен.

    Просто переставьте их местами. Где-то у вас перепутан порядок R и B в 16/32 битах цвета.


    1. JordanCpp Автор
      24.01.2025 09:24

      Спасибо понял. Я копирую в память созданного bitmap RGB, а он принимает BGR.

      Тогда буду, до копирования массив пикселей преобразовывать в BGR, копировать в bitmap, потом обратно в RGB. Не знаете, почему в Windows приняли решение с BGR? К примеру в xlib, openGL и вроде как в DirectX, текстуры создаются из RGB массива байт.


      1. da-nie
        24.01.2025 09:24

        Я уже не помню, но, вероятно, тут дело в старшем/младшем байте. В little-endian первым лежит младший байт. Итого, раскладка 32 бит от 31-го к нулевому будет:

        11111111 rrrrrrrr gggggggg bbbbbbbb;

        В памяти это ложится как B,G,R,0xFF. Поэтому, если у вас формат хранения байтовый (массив uint8_t), то задавать вам нужно B,G,R. А вот если uint32_t, то вот как битовая раскладка (0xff<<24)|(r<<16)|(g<<8)|(b<<0).


  1. JordanCpp Автор
    24.01.2025 09:24

    Установил в эмулятор 86box, windows 95 и 98. Хочу все же попытаться собрать на Visual C++ 2.0.

    Ну а далее продукты Borland C++ тех лет.


  1. JordanCpp Автор
    24.01.2025 09:24

    Исправил цветность и протестировал на Windows 98 в эмуляторе.