Affichage des résultats 1 à 4 sur 4

Discussion: [WeiDU] Définition automatique des variables RGB dans les effets #51 et 52

  1. #1
    Date d'inscription
    April 2011
    Localisation
    Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
    Messages 
    4 644

    [WeiDU] Définition automatique des variables RGB dans les effets #51 et 52

    Tous ceux qui ont utilisé les effets de coloration avec les effets 51 [Colour: Strong/Dark by RGB] et 52 [Colour: Very Bright by RGB] avec un tp2 ont dû se taper la saisie dans DLTCEP, puis un copie-coller de la variable du paramètre 1 dans leur tp2.

    Pour rappel :

    Citation Envoyé par IESDP
    Alters the colour of the area specified by the 'Location and Speed' field, to the colour specified by the 'RGB colour' field.

    The 'RGB Colour' field is handled as follows:
    Second byte = Red (0-255)
    Third byte = Green (0-255)
    Fourth byte = Blue (0-255)
    J'ai voulu automatiser cette procédure en utilisant directement les valeurs RGB dans une fonction.

    En utilisant la définition du paramètre 1 [0x0004 - 4 (dword) - Parameter 1], plutôt qu'utiliser la commande WRITE_LONG, je peux décomposer la variable en 4 WRITE_BYTE, dont la première
    variable est égale à 0 et les trois suivantes aux variables Red, Green et Blue.

    Ce qui me donne :

    Code:
    DEFINE_PATCH_FUNCTION ~GW_DEF_RGB_COLOR~
    	INT_VAR	GW_red	 = 0
    		GW_green = 0
    		GW_blue	 = 0
    	RET	GW_color
    BEGIN
    
    	SET GW_color = (256 * GW_red) + (65536 * GW_green) + (16777216 * GW_blue)
    
    END
    Et ça ne fonctionne pas !

    Du coup, j'ai essayé de comprendre pourquoi et j'ai découvert de manière empirique un truc bizarre : c'est la variable blue qui pose problème.
    Plus exactement, dès qu'elle est supérieure à 127, elle devient négative : -16777216 * GW_blue.
    Problème, la commande
    Code:
     SET GW_blue2 = (0 - GW_blue * 16777216)
    me renvoie tout de même une valeur positive.

    Alors, j'ai bidouillé un truc qui fonctionne :

    Code:
    DEFINE_PATCH_FUNCTION ~GW_DEF_RGB_COLOR~
    	INT_VAR	GW_red	 = 0
    		GW_green = 0
    		GW_blue	 = 0
    	RET	GW_color
    BEGIN
    
    	SET GW_blue2 = GW_blue * 16777216
    
    	PATCH_IF ("%GW_blue%" > 127) BEGIN
    
    		SPRINT GW_blue2 EVAL "%GW_blue2%"
    
    	END
    
    	PATCH_PRINT "TEST de CONTROLE de GW_DEF_RGB_COLOR pour blue = %GW_blue%	==>	GW_blue2 = %GW_blue2%"
    
    	SET GW_color = (256 * GW_red) + (65536 * GW_green) + GW_blue2
    
    	PATCH_PRINT "TEST de CONTROLE GW_DEF_RGB_COLOR - red = %GW_red% - green = %GW_green% - blue = %GW_blue%	==> color = %GW_color%"
    
    END
    Que j'ai simplifié en :

    Code:
    DEFINE_PATCH_FUNCTION ~GW_DEF_RGB_COLOR~
    	INT_VAR	GW_red	 = 0
    		GW_green = 0
    		GW_blue	 = 0
    	RET	GW_color
    BEGIN
    
    	SET GW_blue2 = GW_blue * 16777216
    
    	SPRINT GW_blue2 EVAL "%GW_blue2%"
    
    	SET GW_color = (256 * GW_red) + (65536 * GW_green) + GW_blue2
    
    	PATCH_PRINT "TEST de CONTROLE de GW_DEF_RGB_COLOR - red = %GW_red% - green = %GW_green% - blue = %GW_blue%	==> color = %GW_color%"
    
    END
    Puis je lance :

    Code:
    LPF ~ADD_CRE_EFFECT~ INT_VAR opcode = 51 target = 1 duration = 9 parameter1 = GW_color END
    Et ma créature bénéficie de l'effet de recoloration !

    Le but du jeu étant d'utiliser un tableau de recoloration (opcode, red, green, blue, location => color) appelé si nécessaire par la créature. Une fois mes couleurs définies, si je veux un golem bleu électrique par exemple, je n'ai plus qu'à utiliser la variable color = electric_blue. Idem pour les autres créatures ou les autres couleurs.

    Bref, ça marche très bien, mais comme j'ai horreur de ne pas comprendre, si l'un de vous a une explication, je suis preneur.

    D'autant plus que je vais l'utiliser pour les opcodes 8 [Colour: Change by RGB], 9 [Colour: Glow Pulse] et 50 [Colour: Glow by RGB (Brief)], et notamment pour définir le paramètre 2 :

    Citation Envoyé par IESDP
    Location and speed :

    The 'Location' field is handled as follows:
    First byte = Location
    Third byte = Speed (0-255)

    A speed of 0 does not pulsate. A speed of 1 is fastest, and a speed of 255 is slowest.
    Dernière modification par Freddy_Gwendo ; 20/09/2015 à 00h17.
    CARPE DIEM...
    Co-modérateur de La Forge et de La Chambre des Scribes
    Moddeur qui s'arrache les cheveux...

  2. #2
    Date d'inscription
    July 2003
    Localisation
    Plaisir
    Messages 
    6 827
    Le problème vient du fait que la couleur bleue occupe l'octet poids fort du mot de 32 bits. Le codage des entiers utilise le bit de poids en tant que bit de signe lorsqu'un entier représente un nombre signé. De fait la plage des nombres en valeur absolue est deux fois plus faible lorsqu'on considère que c'est signé (2^32 - 1, soit 2147483647). Pour trouver le code associé à une valeur négative, le langage fait l'opération 2^32 - valeur absolue de la valeur. Quand tu fais l'opération 0 - valeur négative, tu fais sans doute l'opération inverse (ça dépend du langage dans lequel WeiDU est écrit), ce qui t'amène à trouver une valeur positive probablement inférieure à 2147483647.

    Le gros problème avec WeiDU est qu'on ne peut pas choisir si les nombres que l'on manipule sont signés ou non. Je n'ai trouvé aucune indication dans la documentation sur le fait que les variables de type entier sont signées ou non. La seule référence à cette question se trouve dans les fonctions READ_LONG / READ_SLONG, où la question du signé est traitée, en laissant d'ailleurs supposer que par défaut c'est non signé (peut être pour des raisons historiques, la fonction version SLONG a été ajoutée tardivement).

    Néanmoins le fait que tu aies obtenu une valeur négative laisse supposer que, par défaut, les opérations sont faites avec des nombres signés. Et, vu le contournement que tu as trouvé, SPRINT ou EVAL considère au contraire que les valeurs sont non signées. Malheureusement il n'y a aucune trace d'une telle information dans la documentation. Si tu veux des certitudes, il te faudra interroger Wisp sur le forum WeiDU.

    Concernant l'autre cas d'utilisation que tu envisages, le champ qui te préoccupe est sur les 3ème octet et non le quatrième comme ici le code du bleu. Tu multiplieras par 65536 pour calculer la valeur globale et par conséquent il ne devrait pas entraîner un passage du nombre reconstitué dans le monde négatif.


    Alternative possible : calculer ta valeur sur 24 bits puis décaler de 8 vers la droite
    Code:
    SET GW_color = ((GW_red) + (256 * GW_green) + (65536 * GW_blue)) BLSL 8
    Du coup, pas d'impact sur le bit de signe dans le calcul, le décalage à gauche décalera les 24 bits sans y toucher et introduira des 0 dans les 8 bits de poids faible.
    En principe... reste à savoir si c'est le SET ou la gestion du = qui introduisent la bascule dans le monde négatif car dans ce cas, ma suggestion n'aura aucun effet.
    Dernière modification par Isaya ; 20/09/2015 à 11h28.
    Peu disponible
    Guide d'installation (et FAQ) de Baldur's Gate, Baldur's Gate II, Baldur's Gate Trilogy (BGT), BG1Tutu, Widescreen, BGEE
    Pensez à utiliser à la fonction Recherche pour trouver une réponse à votre question !

  3. #3
    Date d'inscription
    April 2011
    Localisation
    Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
    Messages 
    4 644
    Un grand merci !

    Citation Envoyé par Isaya Voir le message
    Alternative possible : calculer ta valeur sur 24 bits puis décaler de 8 vers la droite
    Code:
    SET GW_color = ((GW_red) + (256 * GW_green) + (65536 * GW_blue)) BLSL 8
    Du coup, pas d'impact sur le bit de signe dans le calcul, le décalage à gauche décalera les 24 bits sans y toucher et introduira des 0 dans les 8 bits de poids faible.
    En principe... reste à savoir si c'est le SET ou la gestion du = qui introduisent la bascule dans le monde négatif car dans ce cas, ma suggestion n'aura aucun effet.
    J'ai fait le test avec la fonction suivante :

    Code:
    DEFINE_PATCH_FUNCTION ~GW_DEF_RGB_COLOR~
    	INT_VAR	GW_red	 = 0
    			GW_green = 0
    			GW_blue	 = 0
    	RET		GW_color
    BEGIN
    	SET GW_blue2 = GW_blue * 16777216
    
    	SPRINT GW_blue2 EVAL "%GW_blue2%"
    
    	PATCH_PRINT "blue = %GW_blue%	==>	GW_blue2 = %GW_blue2%"
    	SET GW_color = (256 * GW_red) + (65536 * GW_green) + GW_blue2
    
    	SET GW_color_Isaya = ((GW_red) + (256 * GW_green) + (65536 * GW_blue)) BLSL 8
    	SET GW_color_Isaya2 = ((GW_red) + (256 * GW_green) + (65536 * GW_blue)) << 8
    
    	PATCH_PRINT "red = %GW_red% - green = %GW_green% - blue = %GW_blue%	==> color = %GW_color% / GW_color_Isaya = %GW_color_Isaya% - %GW_color_Isaya2%"
    
    END
    Résultats :

    Code:
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 238 GW_green = 205 GW_blue = 180 RET GW_color END	// -1261572608
    
    	blue = 180	==>	GW_blue2 = -1275068416
    
    	red = 238 - green = 205 - blue = 180	==> color = -1261572608 / GW_color_Isaya = -1261572608 - -1261572608
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 4 GW_green = 7 GW_blue = 7 RET GW_color END		// 117900288
    
    	blue = 7	==>	GW_blue2 = 117440512
    
    	red = 4 - green = 7 - blue = 7	==> color = 117900288 / GW_color_Isaya = 117900288 - 117900288
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 8 GW_green = 5 GW_blue = 5 RET GW_color END		// 84215808
    
    	blue = 5	==>	GW_blue2 = 83886080
    
    	red = 8 - green = 5 - blue = 5	==> color = 84215808 / GW_color_Isaya = 84215808 - 84215808
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 7 GW_green = 7 GW_blue = 4 RET GW_color END		// 67569408
    
    	blue = 4	==>	GW_blue2 = 67108864
    
    	red = 7 - green = 7 - blue = 4	==> color = 67569408 / GW_color_Isaya = 67569408 - 67569408
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 10 GW_green = 245 GW_blue = 245 RET GW_color END	// -168490496
    
    	blue = 245	==>	GW_blue2 = -184549376
    
    	red = 10 - green = 245 - blue = 245	==> color = -168490496 / GW_color_Isaya = -168490496 - -168490496
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 20 GW_green = 8 GW_blue = 0 RET GW_color END		// 529408
    
    	blue = 0	==>	GW_blue2 = 0
    
    	red = 20 - green = 8 - blue = 0	==> color = 529408 / GW_color_Isaya = 529408 - 529408
    
    
    LPF ~GW_DEF_RGB_COLOR~ INT_VAR GW_red = 255 GW_green = 0 GW_blue = 0 RET GW_color END		// 65280
    
    	blue = 0	==>	GW_blue2 = 0
    
    	red = 255 - green = 0 - blue = 0	==> color = 65280 / GW_color_Isaya = 65280 - 65280
    Ça fonctionne parfaitement, et surtout c'est beaucoup plus clair !


    Le gros problème avec WeiDU est qu'on ne peut pas choisir si les nombres que l'on manipule sont signés ou non. Je n'ai trouvé aucune indication dans la documentation sur le fait que les variables de type entier sont signées ou non. La seule référence à cette question se trouve dans les fonctions READ_LONG / READ_SLONG, où la question du signé est traitée, en laissant d'ailleurs supposer que par défaut c'est non signé (peut être pour des raisons historiques, la fonction version SLONG a été ajoutée tardivement).

    Néanmoins le fait que tu aies obtenu une valeur négative laisse supposer que, par défaut, les opérations sont faites avec des nombres signés. Et, vu le contournement que tu as trouvé, SPRINT ou EVAL considère au contraire que les valeurs sont non signées. Malheureusement il n'y a aucune trace d'une telle information dans la documentation. Si tu veux des certitudes, il te faudra interroger Wisp sur le forum WeiDU.
    Pour tout t'avouer, je me sens moyennement me lancer dans une telle discussion technique avec Wisp sur un sujet que je ne maîtrise pas du tout.
    C'est juste un petit miracle que je me sois rappelé l'astuce du SPRINT EVAL que j'ai utilisée pour lire des fichiers 2da et jongler entre des noms de variables textes et entières ayant la même dénomination.

    Concernant l'autre cas d'utilisation que tu envisages, le champ qui te préoccupe est sur les 3ème octet et non le quatrième comme ici le code du bleu. Tu multiplieras par 65536 pour calculer la valeur globale et par conséquent il ne devrait pas entraîner un passage du nombre reconstitué dans le monde négatif.
    Là, je ne me faisais pas trop de soucis car tous mes tests sur la valeur green (la troisième) fonctionnaient.

    Mais au moins je comprend mieux ce que j'ai codé et ça va me permettre de revoir mon codage de la valeur des kits et peut-être la simplifier.

    Puis je me replonge dans la procédure de copie de la structure d'un fichier bam dans un autre. Mais ça, c'est pas gagné...
    Dernière modification par Freddy_Gwendo ; 26/09/2015 à 04h38.
    CARPE DIEM...
    Co-modérateur de La Forge et de La Chambre des Scribes
    Moddeur qui s'arrache les cheveux...

  4. #4
    Date d'inscription
    April 2011
    Localisation
    Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
    Messages 
    4 644
    Dans un souci de simplification, j'ai trouvé une méthode beaucoup plus simple ce weekend :

    Pour le code RGB :

    Code:
    SET GW_color_RGB = (GW_red << 8) + (GW_green << 16) + (GW_blue << 24)

    Pour les variables "pulse" (qui combinent emplacement et vitesse) :

    Code:
    SET GW_pulse = (GW_location) + (GW_speed << 16)
    CARPE DIEM...
    Co-modérateur de La Forge et de La Chambre des Scribes
    Moddeur qui s'arrache les cheveux...

Discussions similaires

  1. [WeiDU] Utilisation de plusieurs fichiers .TRA dans le setup.tp2
    Par Cocrane dans le forum Programmation WeiDU
    Réponses: 3
    Dernier message: 07/02/2016, 19h24
  2. [BG2][BUG] [SPOILER] Demande de global variables pour réparer un trou dans le scénario
    Par Folken dans le forum La Taverne d'Amkethran (Baldur's Gate 2)
    Réponses: 2
    Dernier message: 13/03/2010, 09h32
  3. [BGT] Importer une sauvegarde TUTU dans BGT-WeiDU
    Par LEr0ck dans le forum Baldur's Gate Reloaded : les mods TUTU et Baldur's Gate Trilogy
    Réponses: 2
    Dernier message: 25/02/2010, 15h01
  4. [WORLDMAP] Comment modifier la Worldmap avec WeiDU ?
    Par Dargor dans le forum Cartes et Cartes du monde
    Réponses: 2
    Dernier message: 06/02/2005, 12h24
  5. [ITM] Comment créer un objet à effets aléatoires ?
    Par Lamnis Valnon dans le forum Objets et magasins
    Réponses: 14
    Dernier message: 31/08/2003, 19h11

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250