I created all decoder now (IMG1/IMG2/TXT2/COD2/...) and fighting with gui design:

Feedback welcome. Its coded in Python -> Sourcecode will follow on github.
I don't know... Did you have a look at ReDMCSB source code? The answer must be in there (in file COORD.C).Oh and while we are at it. I read that i follow the whole list of LAY1 to understand the X and Y + W and H.. but how do i handle the Alignments then? exp:
1 DIMENSIONS, 0, 320, 200
Code: Select all
while (L2298_ps_LayoutRecord->ParentRecordIndex) {
switch (L2306_i_) {
default:
return NULL;
case 0:
L2301_ -= ((L2299_ps_LayoutRecord2->Data2 + 1) >> 1);
case 5:
L2300_i_ -= ((L2299_ps_LayoutRecord2->Data1 + 1) >> 1);
break;
case 3:
L2301_ -= L2299_ps_LayoutRecord2->Data2 - 1;
case 2:
L2300_i_ -= L2299_ps_LayoutRecord2->Data1 - 1;
break;
case 6:
L2300_i_ -= L2299_ps_LayoutRecord2->Data1 - 1;
case 8:
L2301_ -= (L2299_ps_LayoutRecord2->Data2 + 1) >> 1;
break;
case 7:
L2300_i_ -= (L2299_ps_LayoutRecord2->Data1 + 1) >> 1;
case 4:
L2301_ -= L2299_ps_LayoutRecord2->Data2 - 1;
case 1:
break;
Code: Select all
#define MASK0x0001_WALL_WEST_RANDOM_ORNAMENT_ALLOWED 0x0001
#define MASK0x0002_WALL_SOUTH_RANDOM_ORNAMENT_ALLOWED 0x0002
#define MASK0x0004_WALL_EAST_RANDOM_ORNAMENT_ALLOWED 0x0004
#define MASK0x0008_WALL_NORTH_RANDOM_ORNAMENT_ALLOWED 0x0008
#define MASK0x0008_CORRIDOR_RANDOM_ORNAMENT_ALLOWED 0x0008
Code: Select all
print("DungeonColumnCount", col)
data = dungeon.read_data(col*2)
print("Count SFTC: ",self.hdr['SquareFirstThingCount']*2)
data = dungeon.read_data(self.hdr['SquareFirstThingCount']*2)
print("Count TextDataWordCount: ",self.hdr['TextDataWordCount']*2)
data = dungeon.read_data(self.hdr['TextDataWordCount']*2)
data = dungeon.read_data(self.hdr['ThingCount'][0]*4) # 4, /* Door */
data = dungeon.read_data(self.hdr['ThingCount'][1]*6) # 6, /* Teleporter */
data = dungeon.read_data(self.hdr['ThingCount'][2]*4) # 4, /* Text String */
data = dungeon.read_data(self.hdr['ThingCount'][3]*8) # 8, /* Sensor */
data = dungeon.read_data(self.hdr['ThingCount'][4]*16) # 16, /* Group */
data = dungeon.read_data(self.hdr['ThingCount'][5]*4) # 4, /* Weapon */
data = dungeon.read_data(self.hdr['ThingCount'][6]*4) # 4, /* Armour */
data = dungeon.read_data(self.hdr['ThingCount'][7]*4) # 4, /* Scroll */
data = dungeon.read_data(self.hdr['ThingCount'][8]*4) # 4, /* Potion */
data = dungeon.read_data(self.hdr['ThingCount'][9]*8) # 8, /* Container */
data = dungeon.read_data(self.hdr['ThingCount'][10]*4) # 4, /* Junk */
data = dungeon.read_data(self.hdr['ThingCount'][11]*0) # 0, /* Unused */
data = dungeon.read_data(self.hdr['ThingCount'][12]*0) # 0, /* Unused */
data = dungeon.read_data(self.hdr['ThingCount'][13]*0) # 0, /* Unused */
data = dungeon.read_data(self.hdr['ThingCount'][14]*8) # 8, /* Projectile */
data = dungeon.read_data(self.hdr['ThingCount'][15]*4) # 4 /* Explosion */
Thanks for the info, I have checked this code is also existing in DM2, but for some reason not giving the same expected random ornament. There may be something slightly different I have not spotted yet.ChristopheF wrote: Sat Mar 02, 2024 11:17 am Regarding random ornaments on floors and walls, you can check function F0170_DUNGEON_GetRandomOrnamentOrdinal (both its content, and where it is called from). This is all in file DUNGEON.C in the ReDMCSB source code.
Code: Select all
#include <stdio.h>
int G0272_i_CurrentMapIndex = 0;
int G0273_i_CurrentMapWidth = 18;
int G0274_i_CurrentMapHeight = 18;
int F0169_DUNGEON_GetRandomOrnamentIndex(int P0301_ui_Value1, int P0302_ui_Value2, int P0303_i_Modulo)
{
return ((((P0301_ui_Value1 * 31417) >> 1) + (P0302_ui_Value2 * 11) + 99) >> 2) % P0303_i_Modulo;
/* Pseudorandom number generator */
}
int F0170_DUNGEON_GetRandomOrnamentOrdinal(int P0304_B_RandomOrnamentAllowed,int P0305_i_OrnamentCount, int P0306_i_MapX, int P0307_i_MapY, int P0308_i_Modulo)
{
if (!P0304_B_RandomOrnamentAllowed) return 0;
int L0305_i_RandomOrnamentIndex;
L0305_i_RandomOrnamentIndex = F0169_DUNGEON_GetRandomOrnamentIndex(
2000 + (P0306_i_MapX << 5) + P0307_i_MapY,
3000 + (G0272_i_CurrentMapIndex << 6) + G0273_i_CurrentMapWidth + G0274_i_CurrentMapHeight, P0308_i_Modulo);
printf("RandomOrnamentIndex: %d \n", L0305_i_RandomOrnamentIndex);
printf("P0305_i_OrnamentCount: %d \n", P0305_i_OrnamentCount);
if (L0305_i_RandomOrnamentIndex < P0305_i_OrnamentCount)
{
return L0305_i_RandomOrnamentIndex+1;
}
return 0;
}
#define normalize(a) (a%0x3)
int main() {
// Write C code here
printf("Try programiz.pro\n");
int P0314_i_MapX = 12;
int P0315_i_MapY = 3;
// int P0314_i_MapX = 17;
// int P0315_i_MapY = 11;
int P0313_i_Direction = 0;
int c = F0170_DUNGEON_GetRandomOrnamentOrdinal(1, 4,P0314_i_MapX, ++P0315_i_MapY * (normalize(P0313_i_Direction) + 1), 30);
printf("ValueRet: %d\n", c);
c = F0170_DUNGEON_GetRandomOrnamentOrdinal(1, 4,P0314_i_MapX, P0315_i_MapY * (normalize(++P0313_i_Direction) + 1), 30);
printf("ValueRet: %d\n", c);
c = F0170_DUNGEON_GetRandomOrnamentOrdinal(1, 4,P0314_i_MapX, P0315_i_MapY * (normalize(++P0313_i_Direction) + 1), 30);
printf("ValueRet: %d\n", c);
c = F0170_DUNGEON_GetRandomOrnamentOrdinal(1, 4,P0314_i_MapX, P0315_i_MapY-- * (normalize(++P0313_i_Direction) + 1), 30);
printf("ValueRet: %d\n", c);
return 0;
}
Code: Select all
i16 Hash(i16 P1,i16 P2,i16 P3)
{ // Called from only one place in program.
// P1 is a function of mapX, mapY
// P2 is a function of level, width, and height
// P3 is a small integer like 30 used as arithmetic modulus.
// Result is hash(P1,P2,dungeonDatIndex[0]) % P3
dReg D0, D1;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
D0L = (ui16)P1 * 31417;
D0W = (I16)((D0W >>= 1) & 0x7fff);
D1L = (ui16)P2 * 11;
D0W = sw(D0W + D1W);
D0W = sw(D0W + d.dungeonDatIndex->Sentinel()); // = 13 in my game
D0W = (I16)((D0W >> 2) & 0x3fff);
D0L &= 0xffff;
D0W = sw(D0L % (ui16)(P3));
return D0W;
}
Code: Select all
i16 RandomWallDecoration(i16 P1,i16 P2,i32 mapX,i32 P4,i16 probability)
{ //P4 = n*mapY where n=facing
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
i16 LOCAL_2;
if (P1 != 0)
{
LOCAL_2 = Hash(
(I16)(2000 + (mapX<<5) + P4),
(I16)(3000 + (d.LoadedLevel<<6) + d.width + d.height),
probability);
if (LOCAL_2 < P2)
{
return sw(LOCAL_2 + 1);
};
};
return 0;
}
void TAG00a4a2(SUMMARIZEROOMDATA *rslt ,
i16 P2, //12
i16 P3, //14
i16 P4, //16
i32 facing, //18
i32 mapX, //20
i32 mapY, //22
i32 P8) //24
{
i16 numDecoration, i;
numDecoration = d.pCurLevelDesc->NumRandomWallDecoration();
rslt->decorations[0] = RandomWallDecoration(
P2,
numDecoration,
mapX,
(mapY+1)*(((facing+1)&3)+1),
30);
rslt->decorations[1] = RandomWallDecoration(
P3,
numDecoration,
mapX,
(mapY+1)*(((facing+2)&3)+1),
30);
rslt->decorations[2] = RandomWallDecoration(
P4,
numDecoration,
mapX,
(mapY+1)*(((facing+3)&3)+1),
30);
if ( (P8 != 0)
|| (mapX < 0)
|| (mapX >= d.width)
|| (mapY < 0)
|| (mapY >= d.height) )
{
for (i = 2; i <= 4; i++)
{
if (IsAlcove(sw(rslt->decorations[i-2]-1)))
{
rslt->decorations[i-2] = 0;
};
};
};
}
Code: Select all
short F0169_DUNGEON_GetRandomOrnamentIndex(unsigned short P0301_ui_Value1, unsigned short P0302_ui_Value2, unsigned short P0303_i_Modulo)
{
int d0l = (uint16_t)P0301_ui_Value1 * 31417;
short d0w = (d0l & 0xffff);
d0w = (int16_t)(( d0w>>= 1) &0x7fff);
int d1l = (uint16_t)P0302_ui_Value2 * 11;
d0w = d0w + (d1l &0xffff);
d0w = d0w + 99;
d0w = (int16_t) ((d0w>>2)&0x3fff);
d0w = d0w & 0xffff;
d0w = d0w% P0303_i_Modulo;
return d0w;
/* Pseudorandom number generator */
}
int F0170_DUNGEON_GetRandomOrnamentOrdinal(int P0304_B_RandomOrnamentAllowed,int P0305_i_OrnamentCount, int P0306_i_MapX, int P0307_i_MapY, int P0308_i_Modulo)
{
if (!P0304_B_RandomOrnamentAllowed) return 0;
int L0305_i_RandomOrnamentIndex;
L0305_i_RandomOrnamentIndex = F0169_DUNGEON_GetRandomOrnamentIndex(2000 + (P0306_i_MapX << 5) + P0307_i_MapY, 3000 + (G0272_i_CurrentMapIndex << 6) + G0273_i_CurrentMapWidth + G0274_i_CurrentMapHeight, P0308_i_Modulo);
if (L0305_i_RandomOrnamentIndex < P0305_i_OrnamentCount)
{
return L0305_i_RandomOrnamentIndex + 1;
}
return 0;
}