Qhimm.com Forums
Miscellaneous Forums => Scripting and Reverse Engineering => Topic started by: fuchisasquatch on 2004-08-16 09:10:05
-
I'm just mucking around and i put this TEX reader in my program and it works perfectly for 4/8 bit textures but i cant test it out on 16 bit textures cuz i cant find any.
So can anybody tell me if they know wheres some are..or even if there are any cuz im having a hard time finding any...
-
There were some, but where hmm ... maybe those FF8 opening screens, but they are in .lsz foromat so you have to unpack them first.
-
oh woops sorry...
i didnt specify which game i was talking about..i mean ff7..sorry bout that
-
oh woops sorry...
i didnt specify which game i was talking about..i mean ff7..sorry bout that
Are you speaking of the PC or PS1 version.
For FF7 there are not 16 bit textures. There are 16bit TIMs that are the game change backgroundds. I believe the intro ICON is also a 16 bit TIM as well.
Cyb
-
I can send you some 16 bit textures from FF8 if you want.
-
FF7 uses 8-bit paletted textures, I think.
-
Can anyone help me with these 16 bit tex's ?
I know that they're in format BGR 5-5-5, but I don't really know how to read 5 bits from a word in Delphi. And I know it has something to do with shl operator :P. Can somebody help me ?
-
oh thanks..well i wouldnt have to worry about it then..
-
Can anyone help me with these 16 bit tex's ?
I know that they're in format BGR 5-5-5, but I don't really know how to read 5 bits from a word in Delphi. And I know it has something to do with shl operator :P. Can somebody help me ?
5-5-5 is 15-bit not 16-bit.
Anyway, you would use a bitshift. In C this would be done like this (if you use rgb and the last bit is empty):
Uint16 numberToBeRead
char r, g, b
r = (numberToBeRead & 1111100000000000) >> 11
g = (numberToBeRead & 0000011111000000) >> 6
b = (numberToBeRead & 0000000000111110) >> 1
What these lines do is this. Let's say your incoming value is this:
1110110110110010
(numberToBeRead & 1111100000000000) will turn it into this:
1110100000000000
When you bitshift that, you will get this:
0000000000011101
After everything, your result will be this:
r = 11101
g = 10110
b = 11001
This code may need to be modified on computers with a different endian format.
-
'>>' means bit shift ? In delphi, there's shr command for this I think. Thanks for responce, I'll try this.
Edit: Actually, the unused bit is last, but first one, so binary values must be diffrent, already got that trick.
But now, how to convert it to 16-bit BMP format, which uses 3 bytes to describe one pixel ? Each of these colors is an integer in range 0..31, and in BMP file each color has 0..255. How to convert it ? Multiplying by 8 gives a 248 max value (or 8 minimal value).
-
Now that is going to be difficult. You might have to use a palette. I am unsure about how to do that.
-
In files that Texture Beast creates, there's no pallete. And for example, colors represented in tex as:
FF 7F
In BMP file that the program creates are:
FF FF FF
And so on...
-
I mean a palette look-up system. You would have a table of the correct values for each 5-bit color and use them.
-
Nope, there's only raw data there. Here are example files: TEX file (http://download19.vel.pl/mav/Face_b01.tex), BMP File (http://download19.vel.pl/mav/Face_b01.bmp)
-
I mean you could make a table of the right values manually.
Oh and I think the PSX uses BGR and not RGB.
Try multiplying the colors by 8. You are just going to have to accept the error for now.
-
5-5-5 is 15-bit not 16-bit.
Well actually it fits within 16 bits on a computer, unless the format is bit packed (which in this case would be plane silly and not all that useful). Hence it's 16bits even if only 15 bits are used.
Anyway, you would use a bitshift. In C this would be done like this (if you use rgb and the last bit is empty):
Excessive Quoting Removed
What these lines do is this. Let's say your incoming value is this:
1110110110110010
(numberToBeRead & 1111100000000000) will turn it into this:
1110100000000000
When you bitshift that, you will get this:
0000000000011101
After everything, your result will be this:
r = 11101
g = 10110
b = 11001
This code may need to be modified on computers with a different endian format.
That's assuming if the data was MSB justified. If it's LSB justified all your shifts are wrong. Also if it's the playstation version then it's 1:5:5:5 Alpha:Blue:Green:Red. If not then one has to be sure what the format is. Either way, it's data dependant isn't it?
Anyhow on subject in Delphi it's shr more importantly it depends on what the original data is. If it's the playstation data you will end up creating 32 bit pixels (RGBA or ABGR depending on how your system is).
In C++ I use this
RGBA TMain::BGRTORGBA(UINT16 Clr)
{
RGBA Return;
Return.Red = (Clr & 0x1F) <<3;
Return.Green = (Clr & 0x3E0) >>2;
Return.Blue = (Clr & 0x7C00)>>10;
Return.Alpha =
(((Clr & 0x8000)|| (Clr == 0))>0)?0xFF:0x00;
return Return;
}
Cyb - Good fortune!
-
I just said I was wrong. There textures are arranged 5 bits blue, 5 bits green, 5 bits red, and the extra bit.
-
I think Alhexx would help here, he writed Texture Beast so he knows this for sure. Alhexx, where are you ? :).
-
I think Alhexx would help here, he writed Texture Beast so he knows this for sure. Alhexx, where are you ? :).
What is Texture Beast?
Are you speaking of Ultima per chance?
sfx1999:
not really that big of a deal I wasn't beating on you or at least I wasn't trying to (needs to be qualified I suppose :D ).
-
I can help too, Biturn supports all the .TEX files aswell, and conversion to BMP too :)
if texture is in ARGB 1555 format it means that there is also alpha (transparency) information available; recalculation of the pixels into the RGBA 8888 format ( 4 bytes for a pixel ) would go like this:
alpha = original & 1; //extract alpha bit
original >>= 1; // remove bit from pixel, move all pixels to the right
red = original & 5; // extract 5 bits for red
red = red * 8; // 5 bits store value 0 - 31, so we multiply it to keep value 0 - 255 ( 0 - 248 )
original >>= 5; // shift red out of the pixel
green = ( original & 5 ) * 8;
original >>= 5; // shift green out of the pixel
blue = ( original & 5 ) * 8;
and there you have it. Sometimes alpha information is useless, so you can just ignore it. If the pixel is stored in reverse order ( RGBA 5551 ) then you have to reverse order of the actions in the code.
-
And what about white colour ?
31 * 8 = 248 = F8.
So with this type of conversion you can't get pure white ? But I saw FF FF FF pixels in bmp that Texture Beast created :).
Your program creates good files too.
Cyb: Texture Beast is a program to convert some formats to others, made by Alhexx. You can find it on his site.
-
well it depends ... if you want to make it to FF then multiply it by (255 / 31 ) = 8,2258 and then round it.
But maybe 248 is right value and it should be that way.
-
Nuh 248 is a greyish color. To see your self go into paint and put 248 in each R,G,B box. So it would surely screw up the colors of some images.
-
In Biturn, when you preview TEX file and then BMP file, you can notice brightness change. It's weird because Biturn produces files with GOOD colors, only in preview mode you can see that issue.
Links: TEX file under Biturn (http://download19.vel.pl/mav/biturn_tex.jpg), BMP file under Biturn (http://download19.vel.pl/mav/biturn_bmp.jpg)
-
hmm i was think of something like
(originalcolorval + 1) * 8
that would work for white..but yeah maybe itd screw up the other colors
-
Yep, dark colors would be lighter.
-
oh no woops it would work
eg.
(31 + 1) * 8 = 256
and max color range for BMP is 255..so yeah
-
also black will be grayish (0+1) * 8 = dark gray
-
Yeah it would be. I was thinking bout this for ages and trying all this crap. Weird its confusing. I also searched around and couldnt find anything. But id suggest saving as 24bit BMP anyway since you dont require a palette. But the conversion between ARGB1555 to RGB888 still needs to be worked on.
-
What if you multiplied by 8.23 instead?
31 * 8.23 = 255.14
-
Mirex, can't you post source code from Biturn that handles conversion of 16 bit TEX files to BMP ?
-
Do what I said and make a lookup table like this:
00000 00000000
00001 00001000
00010 00010000
...
...
11110 11110111
11111 11111111
Basically multiply the first number by 8.23 to make a table.
-
hmm i was thinking and i though would this work
use delphi's round function or similar to do something like
newcolval = Round(colorval * (255 / 31))
i dunno if thats sure to work..but give it a try..
EDIT: oh woops thats kinda similar to what sfx1999 said..but i guess that the above way is more accurate even though the rounding off would give the same or very similar answer..
-
It works :o.
Thanks fuchisquatch :).
procedure TForm1.Button1Click(Sender: TObject);
var rgb: word;
r,g,b: byte;
fs: tfilestream;
begin
rgb := $6339;
r := (rgb and $7C00) shr 10;
g := (rgb and $3E0) shr 5;
b := (rgb and $1F);
r := Round(r * (255 / 31));
g := Round(g * (255 / 31));
b := Round(b * (255 / 31));
fs := tfilestream.Create('test', fmCreate);
fs.Write(b, sizeof(b));
fs.Write(g, sizeof(g));
fs.Write(r, sizeof(r));
end;
*runs Delphi*
Now I can implement this to my prog :).
-
Oh cool :D
Man im downloading delphi right now.
I use VB and i can do almost whatever i want and can do with it..but it just pisses me off sometimes..
It doesnt support signed/unsigned longs..and dont even think about quads and floats.. (I needed signed longs in the texture reading program for the 32bit data)
And also the support files you need to distribute with your applications or have a VB run time pack that really annoys me..so yeah im making a switch.
Its good that delphi looks really simple and maybe just as easy as VB. Hmm i would use C/C++ and even learnt everything there is to know about console programming, but when i went into Win32 applications or tried MFC it was just so friggen complicated and at that time i didnt really see a need for C/C++ anyway.
-
I downloaded an addon for Delphi called Castalia 2 yesterday. It's great because it helps you write code while you're writing it, and not as default - when you compile it. For example:
(http://delphi-expert.com/castalia2/brackets2.gif)
Normally you don't see these colour lines, but they help.
Link: Castalia 2.5 (http://delphi-expert.com/)
Btw: I didn't even bother what means signed and unsigned, but I see this is some important stuff... Can someone explain this to me ?
-
Oh right.
Well signed numbers range from a negative value to a positive value where unsigned numbers range from 0 to a higher postive value.
Normally you wouldnt really need to use unsigned numbers unless your involving some advanced calculation and you would use signed numbers for reading data that has no chance of being negative (e.g. file sizes, image widths, ect.)
Unsigned and signed numbers have the same number of bytes so for example:
Signed bytes range from the value -128 to 127
Unsinged bytes range from the value 0 to 255
So you see that if you add 128 to 127 you get 255..and as you can see by that they have the same range ammount.
EDIT: Can i ask what version of delphi your running. Im trying to download "Borland Delphi v7 Studio Enterprise" is that any good..?
-
Now I get it, thanks ;).
I'm using Delphi v7 Personal Enterprise, about 160 Megs, works well :).
-
Oh alright then yeah i guess what im downloading is not bad then. Its 135 MB..and i hope its the real thing cause you cant really trust KaZaA.
-
I did it! :D
But, here's another problem: Now I want to do whole proccess backwards, so I can convert BMP to TEX. I have 3 color values: r,g and b. How can I make 2 byte 15 bit color from them ? :P
-
Ok well to get the value of the number in the range 0 to 31 you would do
texnum = bmpnum / (255 / 31)
then im not sure about delphi as i havent learnt anything bout that yet but can you reverse it like e.g
r := 10 shr (rgb and $7C00);
g := 5 shr (rgb and $3E0);
b := (rgb and $1F);
or something like that... Just muck around with calculations and see what you can come up with.
[/code]
-
But, here's another problem: Now I want to do whole proccess backwards, so I can convert BMP to TEX. I have 3 color values: r,g and b. How can I make 2 byte 15 bit color from them ?
This or something similair should work:
mul = ( 255 / 31 );
rgb = (( r / mul ) shl 10 ) +
(( g / mul ) shl 5 ) +
( b / mul ) ;
-
I ended up with this code:
texfs.Read(kolor, sizeof(kolor));
r := (kolor and $7C00) shr 10;
g := (kolor and $3E0) shr 5;
b := (kolor and $1F);
r := Round(r * (255 / 31));
g := Round(g * (255 / 31));
b := Round(b * (255 / 31));
destfs.Write(r, sizeof(r));
destfs.Write(g, sizeof(g));
destfs.Write(b, sizeof(b));
And it seems to be working fine :). Thank you guys. You can find program on my new site.
Link: MaV's Page (http://mav.subfan.pl)
-
hey nice homepage
-
Please write some comment it you've been there, you can do it on main page.
-
I did it! :D
But, here's another problem: Now I want to do whole proccess backwards, so I can convert BMP to TEX. I have 3 color values: r,g and b. How can I make 2 byte 15 bit color from them ? :P
C/C++
unsigned short RGB;
RGB = (R & 0xFC) <<8;
RGB|= (G & 0xFC) <<2;
RGB|= (B & 0xFC) >> 3;
Delphi
RGB := ( R and $FC) shl 8;
RGB := RGB or ((G and $FC) shl 2);
RGB := RGB or ((B and $FC) shr 3);
That should pack things correctly for you.
Cyb
-
Well, to convert them back, you would do the colors in reverse, like this:
fiveBitR = eightBitR * (31/255)
-
Well, to convert them back, you would do the colors in reverse, like this:
fiveBitR = eightBitR * (31/255)
hmmm I'm not sure you understand the problem you are creating by doing it this way let me explain (knowing a fair amount about compilors).
if you want to use only integer math this is much better (R8 * 31)/255
, this results in taking the integer multiplying it by 31 then deviding the result by 255. Otherwise the compilor will do this instead, 31/255 result is < 1, thus it will create the floating point constant of 31/255. Then it will convert your R8 value to floating point (at runtime) multiply it by the 31/255 constant and convert the result back to an integer and store that integer as the result. The difference is this has quite a few more operations involved and also involves 3 floating point operations. If he wants to do it fast, it's definately not the fast way to do it.
Of course we could then discuse doing this using mmx instructions which is much faster, however It's not really that important to go on and on about how to make the code faster. :lol:
This is so you know that you need to consider what it is you are doing carefully, if you don't wish to have unintended consequences in your code.
Cyb
-
man what the hell sfx1000
Well, to convert them back, you would do the colors in reverse, like this:
fiveBitR = eightBitR * (31/255)
thats exactly the same friggen thing i wrote....
Ok well to get the value of the number in the range 0 to 31 you would do
Code:
texnum = bmpnum / (255 / 31)
* (31 / 255) is the same thing as / (255 / 31) and why are you guys posting crap when he already said he got it to work..
-
man what the hell sfx1000
Well, to convert them back, you would do the colors in reverse, like this:
fiveBitR = eightBitR * (31/255)
thats exactly the same friggen thing i wrote....
It is not the same what are you talking about. Look at this:
(255) * (31/255) = ~31
(255) * (255/31) = ~2097
If you are accusing me of stealing your idea, I didn't. I got the value 8.23 by taking 255 and dividing it by 31. Look:
255/31 = 8.2258064516129032258064516129032
Also, I just realized you don't need parentheses for that. So this would work:
y = x * 31 / 255
x = y * 255 / 31
Ok well to get the value of the number in the range 0 to 31 you would do
Code:
texnum = bmpnum / (255 / 31)
* (31 / 255) is the same thing as / (255 / 31) and why are you guys posting crap when he already said he got it to work..
Because he said he did not know how to convert back.
Cyberman: why does he need speed? If he is making a renderer it can be done before anything is drawn and if it is plain old converter, then it wouldn't even take a second.
-
Woah woah...
Read it again
It is not the same what are you talking about. Look at this:
(255) * (31/255) = ~31
(255) * (255/31) = ~2097
i was comparing
* (31/255) and / (255/31)
Not what you wrote there..and im not accusing you of stealing my idea i just think its pointless to write the same thing.
I already gave the conversion [ / (255 / 31)] and then you posted practically the same thing.
And yeah i agree with you and that speed thing.
Ok well to get the value of the number in the range 0 to 31 you would do
Code:
texnum = bmpnum / (255 / 31)
* (31 / 255) is the same thing as / (255 / 31) and why are you guys posting crap when he already said he got it to work..
Because he said he did not know how to convert back.
he already figured it out without using that..look here
I ended up with this code:
texfs.Read(kolor, sizeof(kolor));
r := (kolor and $7C00) shr 10;
g := (kolor and $3E0) shr 5;
b := (kolor and $1F);
r := Round(r * (255 / 31));
g := Round(g * (255 / 31));
b := Round(b * (255 / 31));
destfs.Write(r, sizeof(r));
destfs.Write(g, sizeof(g));
destfs.Write(b, sizeof(b));
And it seems to be working fine . Thank you guys. You can find program on my new site.
Link: MaV's Page
Ok? So you understand what im saying now..?
-
Guys, guys, don't argue :). Problem is over, solution is above, so there's no need to argue ;).
-
Guys, guys, don't argue :). Problem is over, solution is above, so there's no need to argue ;).
So how are you doing? is your project mostly functional? no smoke let out of you brain :D
Cyb
-
Yes, it's functional (sorry for long respond, I've been on vacation). You can find it on my page (www button :)).