См. внизу сообщения видео с ошибкой.Alexander Shiryaev писал(а):
PixelFormat определена неправильно -- это как минимум.
Чёрт, а ведь действительно в их Wiki ничего не сказано про padding (
https://wiki.libsdl.org/SDL_PixelFormat), а если посмотреть в /usr/include/SDL2/SDL_pixels.h, то там оно есть:
Код:
typedef struct SDL_PixelFormat
{
Uint32 format;
SDL_Palette *palette;
Uint8 BitsPerPixel;
Uint8 BytesPerPixel;
Uint8 padding[2];
Uint32 Rmask;
...
} SDL_PixelFormat;
Эта структура на самом деле нигде не используется, кроме самого SDL2. Она представлена в Surface указателем, поэтому, несмотря на неправильное определение, она ничего не портила.
KeyboardEventDesc я исправил (добавил padding), но не уверен, почему он и до этого исправления работал (правильно распознавал нажатую клавишу). Наверное, Блэкбокс сам добавлял те два байта в качестве выравнивания.
Alexander Shiryaev писал(а):
RenderSetScale определена с ошибкой: float -- это SHORTREAL, а не REAL
Поменял. В других системах REAL и LONGREAL, поэтому я перепутал.
Ошибка всё ещё на месте. То есть всё работает, но стоит мне раскомментировать, например, строчку
Код:
G.ClearScreen;
внутри процедуры Draw, как всё рушится.
G.ClearScreen вызывает ClearToColor(screen, MakeCol(0, 0, 0)) внутри модуля GraphLib,
MakeCol выдаёт INTEGER, screen - это Bitmap (запись), в которой есть поле surface: SDL.Surface.
ClearToColor выглядит так:
Код:
PROCEDURE ClearToColor* (bmp: Bitmap; color: INTEGER);
BEGIN
IF SDL.FillRect(bmp.surface, NIL, color) = 0 THEN END
END ClearToColor;
И вот на этом FillRect и происходит «illegal memory read (ad = 09F0BD08H) 01X». Я не понимаю, откуда он там может взяться, если всё работает. И даже FillRect работает, если его в другом месте вызывать. Например, в том же Draw чуть ниже я делаю:
Код:
rr.x := 10; rr.y := 50; rr.w := 80; rr.h := 60;
IF SDL.FillRect(screen.surface, rr, color) = 0 THEN END;
(* rr - SDL.Rect (не указатель), screen - G.Bitmap *)
и оно не просто не рушится, а даже рисует прямоугольник.
Я сейчас проверил: если я вместо rr пишу NIL, то оно работает и закрашивает весь экран красным цветом. Но только в течение нескольких запусков. При дальнейших запусках рушится. Как такое может быть?
Я только что воспроизвёл это несколько раз подряд. Достаточно в процедуру Run добавить переменную t: T (и даже не надо делать NEW(t) ) и глюк пропадает. Чертовщина какая-то.
Записал видео в качестве доказательства:
https://youtu.be/MnavaBsP1SI (извиняюсь за плохое качество, но суть в том, что я убираю одну единственную строку: «t: T;». T - это POINTER TO RECORD END, объявленный в той же процедуре. NEW(t) не вызывается.
Прилагаю к сообщению архив с текущей версией GraphSdl, GraphLib и SDLTest.