OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 19 Март, 2024 09:26

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 77 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 02:21 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Оказывается, нельзя использовать NEW на массивах записей без метки (см. тип «M» ниже).
Код:
PROCEDURE Do*;
TYPE
  R = RECORD [untagged] x: INTEGER END;
  M = POINTER TO ARRAY OF R;
VAR m: M;
BEGIN
  NEW(m, 10)
  (* Ошибка: NEW not allowed for untagged structures*)
END Do;

Объясните, пожалуйста, почему это считается ошибкой. Ведь R - это записевый тип, размер которого известен в момент компиляции (его же нельзя расширять, т. к. он не помечен словом «EXTENSIBLE», правильно?). То есть R всегда будет занимать 4 байта. Почему же тогда нельзя выделить массив динамически?

Вышел из положения тем, что написал:
Код:
POINTER TO ARRAY OF POINTER TO R


Почему я вообще написал там [untagged]? Потому что этот тип я должен передавать по ссылке в одну из процедур (SDL_FillRect), при этом VAR-параметр надо пометить директивой [nil], а это возможно только с записями, помеченными как [untagged].


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 03:09 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Код:
MODULE TmpM ["SDL2.dll"];

   TYPE
      int = INTEGER;
      Uint32 = INTEGER;
      Uint32Flags = SET;
      Uint8 = SHORTCHAR; (* or BYTE *)
      PtrVoid = POINTER [untagged] TO RECORD [untagged] END;
      Color = POINTER [untagged] TO ColorDesc;
      ColorDesc = RECORD [untagged]
         r, g, b, a: Uint8
      END;
      Palette = POINTER [untagged] TO PaletteDesc;
      PaletteDesc = RECORD [untagged]
         ncolors: int;
         colors: POINTER [untagged] TO ARRAY [untagged] OF ColorDesc;
         version: Uint32;
         refcount: int
      END;
      PixelFormat = POINTER [untagged] TO PixelFormatDesc;
      PixelFormatDesc = RECORD [untagged]
         format: Uint32;
         palette: Palette;
         BitsPerPixel: Uint8;
         BytesPerPixel: Uint8;
         padding: ARRAY [untagged] 2 OF Uint8;
         Rmask, Gmask, Bmask, Amask: Uint32;
         Rloss, Gloss, Bloss, Aloss: Uint8;
         Rshift, Gshift, Bshift, Ashift: Uint8;
         refcount: int;
         next: PixelFormat
      END;
      Rect = POINTER [untagged] TO RectDesc;
      RectDesc = RECORD [untagged]
         x, y: int;
         w, h: int
      END;
      BlitInfo = POINTER [untagged] TO BlitInfoDesc;
      BlitInfoDesc = RECORD [untagged]
         src: POINTER [untagged] TO ARRAY [untagged] OF Uint8;
         srcW, srcH: int;
         srcPitch: int;
         srcSkip: int;
         dst: POINTER [untagged] TO ARRAY [untagged] OF Uint8;
         dstW, dstH: int;
         dstPitch: int;
         dstSkip: int;
         srcFmt: PixelFormat;
         dstFmt: PixelFormat;
         table: POINTER [untagged] TO ARRAY [untagged] OF Uint8;
         flags: int;
         colorkey: Uint32;
         r, g, b, a: Uint8
      END;
      Blit = PROCEDURE [ccall] (src: Surface; srcrect: Rect; dst: Surface; dstrect: Rect): int;
      BlitMap = POINTER [untagged] TO BlitMapDesc;
      BlitMapDesc = RECORD [untagged]
         dst: Surface;
         identity: int;
         blit: Blit;
         data: PtrVoid;
         info: BlitInfoDesc;
         dstPaletteVersion: Uint32;
         srcPaletteVersion: Uint32
      END;
      Surface = POINTER [untagged] TO SurfaceDesc;
      SurfaceDesc = RECORD [untagged]
         flags: Uint32Flags;
         format: PixelFormat;
         w, h: int;
         pitch: int;
         pixels: PtrVoid;
         userdata: PtrVoid;
         locked: int;
         loclData: PtrVoid;
         clipRect: RectDesc;
         map: BlitMap;
         refcount: int
      END;

   PROCEDURE [ccall] FillRect* ["SDL_FillRect"] (dst: Surface; VAR rect: RectDesc; color: Uint32): int;
   PROCEDURE [ccall] FillRects* ["SDL_FillRects"] (dst: Surface; VAR rects: ARRAY [untagged] OF RectDesc; count: int; color: Uint32): int;

END TmpM.


Последний раз редактировалось Alexander Shiryaev Воскресенье, 10 Апрель, 2016 03:36, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 03:24 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
kekc_leader писал(а):
Оказывается, нельзя использовать NEW на массивах записей без метки (см. тип «M» ниже).
Код:
PROCEDURE Do*;
TYPE
  R = RECORD [untagged] x: INTEGER END;
  M = POINTER TO ARRAY OF R;
VAR m: M;
BEGIN
  NEW(m, 10)
  (* Ошибка: NEW not allowed for untagged structures*)
END Do;

Объясните, пожалуйста, почему это считается ошибкой. Ведь R - это записевый тип, размер которого известен в момент компиляции (его же нельзя расширять, т. к. он не помечен словом «EXTENSIBLE», правильно?). То есть R всегда будет занимать 4 байта. Почему же тогда нельзя выделить массив динамически?

Вышел из положения тем, что написал:
Код:
POINTER TO ARRAY OF POINTER TO R


Почему я вообще написал там [untagged]? Потому что этот тип я должен передавать по ссылке в одну из процедур (SDL_FillRect), при этом VAR-параметр надо пометить директивой [nil], а это возможно только с записями, помеченными как [untagged].

Аргумент rect у FillRect -- не массив, и его не нужно выделять динамически.

А вообще NEW для untagged нельзя использовать, потому что отсутствует информация, необходимая для сборки мусора.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 10:44 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
kekc_leader писал(а):
Оказывается, нельзя использовать NEW на массивах записей без метки (см. тип «M» ниже).
Код:
PROCEDURE Do*;
TYPE
  R = RECORD [untagged] x: INTEGER END;
  M = POINTER TO ARRAY OF R;
VAR m: M;
BEGIN
  NEW(m, 10)
  (* Ошибка: NEW not allowed for untagged structures*)
END Do;

Объясните, пожалуйста, почему это считается ошибкой. Ведь R - это записевый тип, размер которого известен в момент компиляции (его же нельзя расширять, т. к. он не помечен словом «EXTENSIBLE», правильно?). То есть R всегда будет занимать 4 байта. Почему же тогда нельзя выделить массив динамически?

Вышел из положения тем, что написал:
Код:
POINTER TO ARRAY OF POINTER TO R


Почему я вообще написал там [untagged]? Потому что этот тип я должен передавать по ссылке в одну из процедур (SDL_FillRect), при этом VAR-параметр надо пометить директивой [nil], а это возможно только с записями, помеченными как [untagged].

Динамическая память в оригинальных Оберонах - типизированая, то есть участки памяти имеют специальную служебную информацию, которую, в том числе, можно использовать для поиска указателей при сборке мусора, что и делается.
Модификатор [untagged] в КП убирает эту информацию. Такие типы используются в низкоуровневом программировании для маппинга или при работе с внешними по отношению к среде выполнения сущностями. В этом случае, внешняя среда предоставляет специальный API для их создания. Т.е. даже если бы в средствами КП можно было выделить такой участок памяти, то непонятно, как и когда его потом освободить в среде с автоматическим управлением памятью. Есть же простое правило - кто память выделил, тот его и освобождает. Я не знаю SDL, но, думается, там есть средства для создания и освобождения таких сущностей. Или "ты что-то делаешь не так".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 14:00 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Вы неправильно поняли.
Я понимаю, что SDL_FillRect принимает RECORD, а не указатель, и я не передаю ему массив. Массив Rect'ов мне нужен для других целей (хотя на самом деле он там не нужен, это скорее пережиток того, что эту надбиблиотеку я писал для Allegro 4, а потом переделал на SDL2, но всё же хотелось бы разобраться, почему КП так реагирует, тогда как в OO2C это работало). У меня есть запись Font с такой структурой:
Код:
Font* = POINTER TO RECORD
  bmp*: Bitmap;
  charW*, charH*: INTEGER;
  charRows*, charsInRow*: INTEGER;
  sprites*: POINTER TO ARRAY OF ARRAY OF POINTER TO SDL.Rect (* Здесь последнего POINTER TO не было *)
END
Bitmap, в свою очередь, это обёртка над SDL_Surface:
Код:
Bitmap* = POINTER TO RECORD
  surface: SDL.Surface;
  w*, h*: INTEGER
END
Шрифт представляет собой прямоугольную картинку с нарисованными на ней буквами, а массив Rect'ов нужен, чтобы представлять метоположение каждой буквы. Сейчас можно обойтись и без этого, просто иметь локальный Rect в процедуре рисования одного символа и в него записывать x, y, w, h. Это было более актуально, когда движок работал на библиотеке Аллегро, там есть понятие SubBitmap, а процедура, которая рисует букву заданным цветом принимала только целый Bitmap (или целый SubBitmap), в ней нет параметра типа SDL'овского Rect'а.
В общем, в данном случае можно обойтись и без такой структуры, но вопрос в другом. Я понимаю, что Оберон обыкновенно сохраняет рядом с каждым массивом и записью информацию о типе элементов и о длине массива. Но посмотрим ещё раз на объявление:
Код:
sprites*: POINTER TO ARRAY OF ARRAY OF SDL.Rect
Ведь массив объявлен Обероновский, без [untagged]. Только запись SDL.Rect помечена как [untagged], и размер её заранее известен. Почему же нельзя написать NEW(font.sprites, font.charRows, font.charsInRow)? При этом КП сохранил бы в метаданных для массива его длину, чтобы можно было освободить память, а элементами массива были бы «непомеченные» записи, длиной в N байт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 16:17 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Не знаю, почему. Но можно было бы сделать так:
Код:
MODULE TmpM1;

   IMPORT SDL := Sdl2Sdl;

   TYPE
      Bitmap* = POINTER TO RECORD
         surface: SDL.Surface;
         w*, h: INTEGER
      END;
      RectDesc = RECORD r: SDL.RectDesc END;
      Font* = POINTER TO RECORD
         bmp*: Bitmap;
         charW*, charH*: INTEGER;
         charRows*, charsInRow*: INTEGER;
         sprites*: POINTER TO ARRAY OF ARRAY OF RectDesc
      END;

   PROCEDURE P;
      VAR font: Font;
         res: SDL.int;
   BEGIN
      (* ... *)
      NEW(font.sprites, font.charRows, font.charsInRow);
      res := SDL.FillRect(font.bmp.surface, font.sprites[0,0].r, 0)
   END P;

END TmpM1.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 17:16 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Хорошая идея. Спасибо.
У меня с этим SDL_RectFill какая-то чертовщина происходит. Он то работает, то нет. Сейчас перестал совсем.
Точнее, на Виндоусе всё работает, а на Линуксовской сборке Блэкбокса - нет. Выдаёт NIL dereference или вот такой трап:
Код:
illegal memory read (ad = B6......)
08X

<system> (pc=B5......, fp=BF......)
<system> (pc=00000009H, fp=0000000AH)
Происходит это на следующей строке:
Код:
IF SDL.FillRect(s, rr, G.MakeCol(255, 0, 0)) = 0 THEN END;
s - это SDL.Surface (указатель), rr - это SDL.Rect (не указатель)...
Я в тупике. На Виндоусе всё работает прекрасно, а на Линуксе вот такая ошибка и хоть убей.

Прилагаю компоненты к сообщению. Их два:
1) Graph (внутри: Sdl.odc и Lib.odc; Lib использует Sdl) и
2) SDLTest (внутри файл SDLTest.odc; использует GraphLib и GraphSdl).
Линуксовская и Виндоуская версия отличаются только в одном месте - разными ссылками на DLL/SO:
Код:
MODULE GraphSdl ["libSDL2.so"];
MODULE GraphSdl ["SDL2.dll"];


Вложения:
Комментарий к файлу: Это SDL2.dll, его надо положить в папку с Блэкбоксом (на Виндоусе)
SDL2.zip [377.36 КБ]
Скачиваний: 403
Комментарий к файлу: Компоненты SDLTest и Graph
Components.zip [14.29 КБ]
Скачиваний: 422
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 17:34 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
kekc_leader писал(а):
Ведь массив объявлен Обероновский, без [untagged]. Только запись SDL.Rect помечена как [untagged], и размер её заранее известен. Почему же нельзя написать NEW(font.sprites, font.charRows, font.charsInRow)? При этом КП сохранил бы в метаданных для массива его длину, чтобы можно было освободить память, а элементами массива были бы «непомеченные» записи, длиной в N байт.

По той же самой причине - рантайм должен знать тип элемента, так как массив объявлен обероновский, то сборщик мусора будет обходить его элементы, а так как элементы структурные - запись, - то должна присутствовать служебная информация от этой записи.
На самом деле, если постараться, то и под untagged можно выделить память, но ни к чему хорошему это не приведет.
Также можно выделит память, через, например, winApi, и замаппить эту сырую память на указатель на untagged массив с untagged записями. И потом не забыть освободить. Но это тоже не айс.
Можно создать дополнительный тип - обероновскую запись такой же структуры как и untagged, и просто при запросе от SDL присваивать значение элементу массива. А при вызове процедуры предварительно копировать в untagged локальную переменную и ее передавать в качестве ссылки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 19:49 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Видимо надо делать Renderer. В SDL2 библиотеке под WIndows наверное больший акцент на обратную совместимость с SDL первой версии сделали.
http://stackoverflow.com/questions/2267 ... dow-issues

Если вы хотите в стиле первой версии SDL программировать, то есть достаточно полный порт уже.
https://sourceforge.net/projects/sdl-for-oberon


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 20:33 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Иван Денисов писал(а):
Видимо надо делать Renderer. В SDL2 библиотеке под WIndows видимо наверное больший акцент на обратную совместимость с SDL первой версии сделали.
Нет, дело точно не в этом. Я создаю Window и Renderer, а в момент прорисовки каждого кадра, Surface переводится в Texture, чтобы Renderer смог её отобразить. Я так делаю, потому что этот единственный способ заставить SDL2 работать быстро даже на старых компьютерах. SDL2 полностью поддерживает Surface из старой версии, в том числе и на Линуксе. Я использовал те же SO-библиотеки, и использовал Surface на Си и на Обероне (через VOC и OO2C), теперь вот хочу перенести это всё на Блэкбокс.

Похоже, что ошибка имеет отношение к этой ветке: http://forum.oberoncore.ru/posting.php?mode=reply&f=2&t=2001 «Проблема с выделением памяти», т. к. когда я добавляю следующий код в некоторые места в программе, ошибка либо переносится на другую строку, либо пропадает:
Код:
TYPE T = POINTER TO RECORD END;
VAR t: T;
BEGIN
  NEW(t);

Возможно, имеет смысл, продолжить обсуждение в той ветке. Вообще, этот форум - золотая жила. За 10 лет тут накопилось огромное количество полезной информации.
Помогите решить проблему, товарищи.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 20:53 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Какую версию BlackBox под Windows используете?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 21:47 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
В GraphLib.Init поставь ASSERT после каждой процедуры возвращающей указатель


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 22:05 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Иван Денисов писал(а):
Какую версию BlackBox под Windows используете?
Школьную сборку отсюда: http://oberoncore.ru/projects/bb-shk. Какую посоветуете?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 22:25 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
kekc_leader писал(а):
Хорошая идея. Спасибо.
У меня с этим SDL_RectFill какая-то чертовщина происходит. Он то работает, то нет. Сейчас перестал совсем.
Точнее, на Виндоусе всё работает, а на Линуксовской сборке Блэкбокса - нет. Выдаёт NIL dereference или вот такой трап:
Код:
illegal memory read (ad = B6......)
08X

<system> (pc=B5......, fp=BF......)
<system> (pc=00000009H, fp=0000000AH)
Происходит это на следующей строке:
Код:
IF SDL.FillRect(s, rr, G.MakeCol(255, 0, 0)) = 0 THEN END;
s - это SDL.Surface (указатель), rr - это SDL.Rect (не указатель)...
Я в тупике. На Виндоусе всё работает прекрасно, а на Линуксе вот такая ошибка и хоть убей.

Прилагаю компоненты к сообщению. Их два:
1) Graph (внутри: Sdl.odc и Lib.odc; Lib использует Sdl) и
2) SDLTest (внутри файл SDLTest.odc; использует GraphLib и GraphSdl).
Линуксовская и Виндоуская версия отличаются только в одном месте - разными ссылками на DLL/SO:
Код:
MODULE GraphSdl ["libSDL2.so"];
MODULE GraphSdl ["SDL2.dll"];


PixelFormat определена неправильно -- это как минимум.

Надо так:
Код:
   TYPE
      PixelFormat* = POINTER [untagged] TO PixelFormatDesc;
      PixelFormatDesc* = RECORD [untagged]
         format*: Uint32;
         palette*: Palette;
         bitsPerPixel*: Uint8;
         bytesPerPixel*: Uint8;
         padding: ARRAY [untagged] 2 OF Uint8;
         Rmask*, Gmask*, Bmask*, Amask*: Uint32;
         Rloss*, Gloss*, Bloss*, Aloss*: Uint8;
         Rshift*, Gshift*, Bshift*, Ashift*: Uint8;
         refCount*: int;
         next*: PixelFormat
      END;


Events тоже:

Код:
   TYPE
      Uint16* = SHORTINT;
      Sint32* = INTEGER;

      CommonEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32
      END;

      WindowEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         event*: Uint8;
         padding1, padding2, padding3: Uint8;
         data1*, data2*: Sint32
      END;

      Scancode* = Sint32; (* TODO: check *)
      Keycode* = Sint32;

      KeysymDesc* = RECORD [untagged]
         scancode*: Scancode;
         sym*: Keycode;
         mod*: Uint16;
         unused: Uint32
      END;

      KeyboardEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         state*: Uint8;
         repeat*: Uint8;
         padding2: Uint8;
         padding3: Uint8;
         keysym*: KeysymDesc
      END;

      TextEditingEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         text*: ARRAY [untagged] TEXTEDITINGEVENT_TEXT_SIZE OF char;
         start*: Sint32;
         length*: Sint32
      END;

      TextInputEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         text*: ARRAY [untagged] TEXTINPUTEVENT_TEXT_SIZE OF char
      END;

      MouseMotionEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         which*: Uint32;
         state*: Uint32;
         x*, y*, xrel*, yrel*: Sint32
      END;

      MouseButtonEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         which*: Uint32;
         button*, state*, clicks*, padding1: Uint8;
         x*, y*: Sint32
      END;

      MouseWheelEventDesc* = RECORD [untagged]
         type*: Uint32;
         timestamp*: Uint32;
         windowID*: Uint32;
         which*: Uint32;
         x*, y*: Sint32;
         direction*: Uint32
      END;

      EventDesc* = RECORD [union]
         type*: Uint32;
         common*: CommonEventDesc;
         window*: WindowEventDesc;
         key*: KeyboardEventDesc;
         edit*: TextEditingEventDesc;
         text*: TextInputEventDesc;
         motion*: MouseMotionEventDesc;
         button*: MouseButtonEventDesc;
         wheel*: MouseWheelEventDesc;
         padding: ARRAY [untagged] 56 OF Uint8
      END;

(насчёт Scancode и KeysymDesc не уверен -- надо разбираться)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Воскресенье, 10 Апрель, 2016 23:23 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
RenderSetScale определена с ошибкой: float -- это SHORTREAL, а не REAL


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Понедельник, 11 Апрель, 2016 00:36 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
См. внизу сообщения видео с ошибкой.
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.


Вложения:
Комментарий к файлу: GraphSdl, GraphLib и SDLTest, используемые в видео-ролике https://youtu.be/MnavaBsP1SI
Components2.zip [14.57 КБ]
Скачиваний: 425
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Понедельник, 11 Апрель, 2016 01:25 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Нужно исправить все структуры Event, как я написал. Заметил ещё, что ARRAY без untagged в KeyboardEvent.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Понедельник, 11 Апрель, 2016 02:07 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Написал для контроля такую программку на Си. Сейчас буду всё проверять.
Код:
#include <stdio.h>
#include <SDL2/SDL.h>

int main() {
  printf("SDL_KeyboardEvent = %d\n", sizeof(SDL_KeyboardEvent));
  printf("SDL_WindowEvent = %d\n", sizeof(SDL_WindowEvent));
  printf("SDL_Event = %d\n", sizeof(SDL_Event));
  printf("SDL_MouseMotionEvent = %d\n", sizeof(SDL_MouseMotionEvent));
  printf("SDL_MouseButtonEvent = %d\n", sizeof(SDL_MouseButtonEvent));
  printf("SDL_MouseWheelEvent = %d\n", sizeof(SDL_MouseWheelEvent));
  printf("SDL_TextEditingEvent = %d\n", sizeof(SDL_TextEditingEvent));
  printf("SDL_TextInputEvent = %d\n", sizeof(SDL_TextInputEvent));
  printf("SDL_PixelFormat = %d\n", sizeof(SDL_PixelFormat));
  printf("SDL_Keysym = %d\n", sizeof(SDL_Keysym));
  printf("SDL_DisplayMode = %d\n", sizeof(SDL_DisplayMode));
  printf("SDL_Palette = %d\n", sizeof(SDL_Palette));
  printf("SDL_Rect = %d\n", sizeof(SDL_Rect));
  printf("SDL_Surface = %d\n", sizeof(SDL_Surface));
  return 0;
}
/* Compile: gcc -lSDL2 a.c */

Вывод:
Код:
SDL_KeyboardEvent = 32
SDL_WindowEvent = 24
SDL_Event = 56
SDL_MouseMotionEvent = 36
SDL_MouseButtonEvent = 28
SDL_MouseWheelEvent = 24
SDL_TextEditingEvent = 52
SDL_TextInputEvent = 44
SDL_PixelFormat = 44
SDL_Keysym = 16
SDL_DisplayMode = 20
SDL_Palette = 16
SDL_Rect = 16
SDL_Surface = 60


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Понедельник, 11 Апрель, 2016 02:19 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
Цитата:
Код:
SDL_MouseWheelEvent = 24


Непонятно, почему.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW для структур без метки (untagged)
СообщениеДобавлено: Понедельник, 11 Апрель, 2016 02:26 
Аватара пользователя

Зарегистрирован: Среда, 22 Апрель, 2015 23:51
Сообщения: 248
Откуда: г. Рига, Латвийская ССР
Alexander Shiryaev писал(а):
Цитата:
Код:
SDL_MouseWheelEvent = 24
Непонятно, почему.

Код:
/* /usr/include/SDL2/SDL_events.h */
typedef struct SDL_MouseWheelEvent
{
    Uint32 type;        /**< ::SDL_MOU...
    Uint32 timestamp;
    Uint32 windowID;    /**< The windo...
    Uint32 which;       /**< The mouse...
    Sint32 x;           /**< The amoun...
    Sint32 y;           /**< The amoun...
} SDL_MouseWheelEvent;
Тут и получается 24. В других случаях есть несостыковки, например, должно быть 21, а оно 24. Я думаю, это выравнивание компилятора. Если посомтреть в список, то размеры всех структур кратны 4-м.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 77 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB