Простая замена вариантного типа в исходных кодах Borland Pascal

Спасибо! Но это всё равно означает, что придётся полностью переделывать весь имеющийся код. Гигантская работа, и как говорится: “овчинка выделки не стоит”. Придётся видимо под ДОСом оставаться :frowning:

Старую собаку не научишь новым штукам.

Может, проще это пристрелить, чтобы не мучиться? ))

А разве union так часто нужен?

В моих проектах переменные этого типа почти в каждой строчке кода (выше писал).

Нет, это я услышал, но зачем? Мне за всё время сколько я программировал - такое меньше 10 раз понадобилось…

Компилятор/декомпилятор. В исходном бинарном файле всё вперемешку же. Примерно так: Из этого

Z*level5.mazД°party has gained 800 points of experience.
ю ю8·ш
ю юs·їыю юА·їёїЁёїЁёїЁёЎaуЎ
у ўу

получть это

[Part 1]
{1A2A}		;Смещение, с которого начинается Part 5 (разумеется за вычетом -0Ah)
"level5.maz", 00, 00 ;Maze name (12 байт, после первого $00 байты игнорируются)
"blue", 00, "5.maz", 00, 00 ;VCN/VMP name (12 байт, после первого $00 байты игнорируются)
"blue", 00, "5.maz", 00, 00 ;Palette name (12 байт, после первого $00 байты игнорируются)
02, 00, FF, 03			;Nb of doors and doorknobs (???)
02, 00, 00, 32, 00			;Max monster / tdiff etc (???)
01			;Number of procedure for extraction of monster picture (???)
"dwarf", 00, ".maz", 00, 00 ;Name Of Monster pic CPS file (12 байт, после первого $00 байты игнорируются)
02			;Number of procedure for extraction of monster picture (???)
"spider", 00, "maz", 00, 00 ;Name Of Monster pic CPS file (12 байт, после первого $00 байты игнорируются)
00, 19			;Timer0 | Timer 1| Timerdiff (in Ticks)
01, 0F			;Timer0 | Timer 1| Timerdiff
FF			;End of Timer

А потом, после редактирования, скомпилировать назад в бинарный файл.

Ну, вот участок декомпилятора (переменные ubd и uchd):

with UDest do begin
{Алгоритм bytes2string
        b1 - текущая позиция в строке (от 0);
        b2 - 0: предыдущий символ был не буквой, 1: предыдущий символ был буквой}
	b1:=0;for j:=1 to 12 do begin
	read(fn1b,ubd);
	case ubd of
	0..31,127,176..223, 242..255: begin
		if b1=0 then write(fn2,dec1hex(ubd))
		else
			if b2=0 then write(fn2,', '+dec1hex(ubd))
			else write(fn2,'", '+dec1hex(ubd));
	b2:=0 end
	else begin
		if b1=0 then begin write(fn2,'"'+uchd);if uchd='"' then write(fn2,'"') end
		else
			if b2=0 then begin write(fn2,', "'+uchd);if uchd='"' then write(fn2,'"') end
			else begin write(fn2,uchd); if uchd='"' then write(fn2,'"') end;
	b2:=1 end
	end;{case}
	inc(b1);
	end;{for j}

То есть вы декомпилируете и назад компилируете программу только чтоб поменять несколько значений?))) Это разве не гипер костыль, даже как на програминг прошлого века?)))

Да, пристрелить хобби (+дело всей жизни), и умереть.

Не бывалому ли в IT знать что такой бред надо просто игнорить?)))

И, если хотите - я мог бы помочь при переводе (хотя сначала хотелось бы увидеть с чем работать придётся). Меня интересует подобное (инди игры и неординарные случаи в програминге, как перевод с чего то древнего).

Не программу, скрипты. Штук 40.

Не несколько, много, очень много в разных местах. Багов много, недоделок много (известная проблема при давлении издателей на разработчиков).

Здесь же я только пример привёл.

Ну, в .Net не важно так то сколько значений заменять. Для этого есть на много более красивые способы, при чём не порождающие и близко на столько же много багов.

Вариантного типа нет в PascalABC.NET. Мы средствами NET не смогли его нормально промоделировать

Ну как это, если в IL коде у структур указывается номер байта куда будет сувать поле, что там не мочь:

image

Ведь так это и делается, разве нет?

Мм. Можно попробовать добавить read/write свойства, которые будут преобразовывать переданную переменную в ту, что хранится единственным полем нужного размера в структуре, разве что… Но работать будет не везде - только там, где есть однозначное преобразование между типами в импровизированном union.

А вообще, использовать union как замену reinterpret_cast (то, что предлагает ТС) - глупость. Его не для того задумывали…

Вообще, знаю только один годный юзкейс (с работы) использования union’ов. Когда нужно организовать сетевой обмен через модем 1200 бод (эффективная скорость обмена 120 байт/сек), и каждый бит в структуре дорог, как бабушкины пирожки.

Ну, именно так все костыл-е-union-ы, предназначенные работать именно как union-ы, что вы я видел в C# и работали.

То что так не задумывалось - совсем не значит что тот кто так делает глуп. Я больше скажу, если такое решение работает - оно очень даже умно. К примеру в SharpDX есть тип-угол. Значение угла хранится в поле типа single, а хешкод читается из перекрывающего его поля типа integer. Я видел только 1 другой способ, через указатели, сделать reinterpret_cast в .Net, и этот способ на много лучше (чище работает).

Движок форума сообщил, что заблокировал мне, как новичку, отправку сообщений на час:

Час прошёл, движок форума мне сообщил:

==================================================================

Увы :frowning: Жаль, что Вы так подумали.

Серия игр старая, 1990-х годов. Eye of the beholder.

Если Вам действительно интересно, стоит перейти на какую-либо другую площадку, где можно свободно передавать файлы. Здесь дальнейшее обсуждение именно моего проекта - off-topic.

Да уж, очень странно. В C union живёт и здравствует, а разработчики паскалей решили такой тип ликвидировать.

Понятно, спасибо!

Хорошая была игра. Только конец какой-то комканый. Но в целом - правильная AD&D. Второй бехолдер мне не понравился.

Его не ликвидировали, его просто решили не делать с самого начала, так как в нём нет особой необходимости в .NET - языке.

Собственно, Вам показали, как его сделать:

uses System.Runtime.InteropServices;

type
  [StructLayout(LayoutKind.&Explicit)]
  SomeValType = record
    [FieldOffset(0)]
    b: byte; 
    [FieldOffset(0)]
    x: integer;
  end;

1 лайк

“Бисмиллях ир-рахман ир-рахим!» …” (с)