First Read this:
http://130.113.54.154/~monger/hsl-rgb.html
it's a little confusing but whatever. ._.
Anyways the purpose of making this is so that I can try and Make a color cycler. Normally, this would require sin or cosine, but since i'm not going the LUT route on this, I decided that an HSL to RGB converter where the degrees of hue change would be more appropriate, since you eliminate the need for sine or cosine completely.
I'm having some problems though, and i'm not entirely sure why. Its not with the formula, I know it works, it's just my iffy assembly isn't producing the results I'd like. Specifically it's outputting 000007FF as the color always, It's an ugly shade of blue. Unfortunately, I worked without leaving myself many notes to follow and I now find myself worked in a corner. :(
Hopefully some of the fine hackers here can help me debug this ugly mess.
heres the assembly:
# RAM Simul RR GG BB AA
# 00000000 04000000 08000000 0C000000 10 11 12 13 14000000 18000000
# 00000000 00000000 00000000 00000000 00 00 00 00 00000000 00000000
# shadef lightf speedinc huetemp colorfin alpha? coltemp
#
# Fix Value Simul
# 00000000 04000000 08000000 0C000000 10000000 14000000 18000000 1C000000
# 00000000 3F000000 40000000 3EAAAAAB 3F2AAAAB 40C00000 3F800000 437F0000
# 0 .5 2 1/3 2/3 6 1 255
.set rambaseh,0x8000
.set rambasel,0x0000
.set fixvalh,0x8000
.set fixvall,0x0000
.set fixreg,17
.set basereg,14
.set tempf,21
.set colorf,20
.set colorreg,15
.set alpha,16
.set shadef,30 #this is saturation (don't let shade confuse you)
.set huef,27
.set rate,26
.set lightf,31
.set temp2,28
.set temp1,29
.set tempf2,25
.set temp3R,18
.set temp3G,19
.set temp3B,20
stackframe:
stwu r1,-124(r1) #allocate room for r14-r31
stmw r14,8(r1) #load r14-r31 into stackframe
stmw f20,88(r1) #load f20-f31 into stackframe
lis fixreg,fixvalh
ori fixreg,fixreg,fixvall
lis basereg,rambaseh
ori basereg,basereg,rambasel
lfs lightf,4(basereg)
lfs shadef,0(basereg)
lwz alpha,0x14(basereg)
lfs tempf,0(fixreg)
fcmpu cr0,shadef,tempf
bne skiplightforce
#colors in this area forced to grayscale
fctiw colorf,lightf #float convert to integer word
stfs colorf,0x18(basereg)
lwz colorreg,0x18(basereg)
stb colorreg,0x10(basereg)
stb colorreg,0x11(basereg)
stb colorreg,0x12(basereg)
stb alpha,0x13(basereg)
skiplightforce:
lfs tempf,4(fixreg)
fcmpu cr0,lightf,tempf
blt dark
fmuls temp2,lightf,shadef
fadds shadef,lightf,shadef #shade no longer important, so overwritten
fsubs temp2,shadef,temp2 #L+S-(L*S)
b settemp1
dark:
lfs temp2,0x18(fixreg)
fadds temp2,temp2,shadef
fmuls temp2,temp2,lightf
settemp1:
lfs tempf,8(fixreg) #load 2
fmuls temp1,tempf,lightf
fsubs temp1,temp1,temp2
#begin hue calculations
lfs huef,0x0C(basereg)
lfs rate,8(basereg)
lfs shadef,0x18(fixreg) #shadef used as second temp floatreg
fcmpu cr0,tempf,shadef
fadds tempf,huef,rate
ble storehue
lfs tempf,0(fixreg) #resets to 0, values can only be 0-1
storehue:
stfs tempf,0x0C(basereg) #necessary for cycle
#start RR
lfs tempf,0x0C(fixreg)
fadds temp3R,huef,tempf
lfs tempf,0(fixreg)
fcmpu cr0,tempf,temp3R
blt add1RR
lfs tempf,0x18(fixreg)
fcmpu cr0,tempf,temp3R
bgt sub1RR
b skipfixRR
add1RR:
lfs tempf,0x18(fixreg)
fadds temp3R,temp3R,tempf
b skipfixRR
sub1RR:
fsubs temp3R,temp3R,tempf
skipfixRR:
#start GG
lfs tempf,0(fixreg)
fcmpu cr0,tempf,temp3G
blt add1GG
lfs tempf,0x18(fixreg)
fcmpu cr0,tempf,temp3G
bgt sub1GG
b skipfixGG
add1GG:
lfs tempf,0x18(fixreg)
fadds temp3G,temp3G,tempf
b skipfixGG
sub1GG:
fsubs temp3G,temp3G,tempf
skipfixGG:
#start BB
lfs tempf,0x0C(fixreg)
fsubs temp3B,huef,tempf
lfs tempf,0(fixreg)
fcmpu cr0,tempf,temp3B
blt add1BB
lfs tempf,0x18(fixreg)
fcmpu cr0,tempf,temp3B
bgt sub1BB
b skipfixBB
add1BB:
lfs tempf,0x18(fixreg)
fadds temp3B,temp3B,tempf
b skipfixBB
sub1BB:
fsubs temp3B,temp3B,tempf
skipfixBB:
#start corrections
#
#
#temp3R fix
lfs tempf,0x14(fixreg)
fmuls tempf,tempf,temp3R
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryR1
fsubs tempf2,temp2,temp1
fmuls tempf2,tempf2,tempf
fadds temp3R,tempf2,temp1
b goodRR
retryR1:
lfs tempf,0x08(fixreg)
fmuls tempf,tempf,temp3R
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryR2
fmr temp3R,temp2
b goodRR
retryR2:
lfs tempf,0x14(fixreg)
lfs tempf2,0x08(fixreg)
fdivs tempf,tempf,tempf2
fmuls tempf,tempf,temp3R
lfs shadef,0x08(fixreg)
fcmpu cr0,tempf,shadef
bge retryR3
lfs tempf,0x10(fixreg)
fsubs temp3R,tempf,temp3R
fsubs tempf,temp2,temp1
fmuls tempf,tempf,temp3R
lfs shadef,0x14(fixreg)
fmuls tempf,shadef,tempf
fadds temp3R,temp1,tempf
b goodRR
retryR3:
fmr temp3R,temp1
goodRR:
lfs tempf,0x1C(fixreg)
fmuls temp3R,tempf,temp3R
fctiw temp3R,temp3R
stfs temp3R,0x18(basereg)
lwz tempf,0x18(basereg)
stb tempf,0x10(basereg)
#red determined & stored
#
#
#temp3G fix
lfs tempf,0x14(fixreg)
fmuls tempf,tempf,temp3G
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryG1
fsubs tempf2,temp2,temp1
fmuls tempf2,tempf2,tempf
fadds temp3G,tempf2,temp1
b goodGG
retryG1:
lfs tempf,0x08(fixreg)
fmuls tempf,tempf,temp3G
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryG2
fmr temp3G,temp2
b goodGG
retryG2:
lfs tempf,0x14(fixreg)
lfs tempf2,0x08(fixreg)
fdivs tempf,tempf,tempf2
fmuls tempf,tempf,temp3G
lfs shadef,0x08(fixreg)
fcmpu cr0,tempf,shadef
bge retryG3
lfs tempf,0x10(fixreg)
fsubs temp3G,tempf,temp3G
fsubs tempf,temp2,temp1
fmuls tempf,tempf,temp3G
lfs shadef,0x14(fixreg)
fmuls tempf,shadef,tempf
fadds temp3G,temp1,tempf
b goodGG
retryG3:
fmr temp3G,temp1
goodGG:
lfs tempf,0x1C(fixreg)
fmuls temp3G,tempf,temp3G
fctiw temp3G,temp3G
stfs temp3G,0x18(basereg)
lwz tempf,0x18(basereg)
stb tempf,0x11(basereg)
#green determined & stored
#
#
#temp3B fix
lfs tempf,0x14(fixreg)
fmuls tempf,tempf,temp3B
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryB1
fsubs tempf2,temp2,temp1
fmuls tempf2,tempf2,tempf
fadds temp3B,tempf2,temp1
b goodBB
retryB1:
lfs tempf,0x08(fixreg)
fmuls tempf,tempf,temp3B
lfs shadef,0x18(fixreg)
fcmpu cr0,tempf,shadef
bge retryB2
fmr temp3B,temp2
b goodBB
retryB2:
lfs tempf,0x14(fixreg)
lfs tempf2,0x08(fixreg)
fdivs tempf,tempf,tempf2
fmuls tempf,tempf,temp3B
lfs shadef,0x08(fixreg)
fcmpu cr0,tempf,shadef
bge retryB3
lfs tempf,0x10(fixreg)
fsubs temp3B,tempf,temp3B
fsubs tempf,temp2,temp1
fmuls tempf,tempf,temp3B
lfs shadef,0x14(fixreg)
fmuls tempf,shadef,tempf
fadds temp3B,temp1,tempf
b goodBB
retryB3:
fmr temp3B,temp1
goodBB:
lfs tempf,0x1C(fixreg)
fmuls temp3B,tempf,temp3B
fctiw temp3B,temp3B
stfs temp3B,0x18(basereg)
lwz tempf,0x18(basereg)
stb tempf,0x12(basereg)
#blue determined & stored
#store alpha value
stb alpha,0x13(basereg)
popstackframe:
lmw r14,8(r1) #read registers r14 to r31 from stack
lmw f20,88(r1) #read registers f20 to f31 from stack
addi r1,r1,124 #free stackframe
in addition to that I have some necessary RAM writes (because I'm also lazy):
this would be an example with 8150000 as the fixvalue area
055000A0 3F800000 //store dynamic variables (lighting, saturation, increase increment, and alpha value)
055000A4 3F000000
055000A8 3E000000
055000B4 000000FF
80000007 815000B0
8A00047F XXXXXXXX //move to address of interest from memory
07500000 00000020 //start fixvalue stuff (shouldn't need changing)
00000000 3F000000
40000000 3EAAAAAB
3F2AAAAB 40C00000
3F800000 437F0000
E0000000 80008000
hopefully you guys can help ._.
bump only minutes after posting because someone posted on another topic about 4 seconds after i posted this :\
is it somehow related to your hacking challenge?
I read that you also participate on it, lol.
Anyway, I also think that you won´t get good help... this thing is too crazy
its not THAT challenging. besides, I think some people here could do it.
Awwww, how come i don't hear about this fun stuff on irc
:S i like to bitch on IRC lol ._.
bump :\ i really want to figure this out pl0x
i know i'm a noob :S
YOU!!!! a NOOB!!!! Get real I'm a noob not you.
i meant for bumping my topic, however, i will do this again as i post this D:
I'm not sure if this has something to do with the problem, but these two instructions are invalid.
stmw f20,88(r1)
lmw f20,88(r1)
Unlike general purpose registers(GPR's), float registers need to be stored/loaded one by one.
[spoiler]stfs f20,88(r1)
stfs f21,92(r1)
stfs f22,96(r1)
stfs f23,100(r1)
stfs f24,104(r1)
stfs f25,108(r1)
stfs f26,112(r1)
stfs f27,116(r1)
stfs f28,120(r1)
stfs f29,124(r1)
stfs f30,128(r1)
stfs f31,132(r1)
lfs f20,88(r1)
lfs f21,92(r1)
lfs f22,96(r1)
lfs f23,100(r1)
lfs f24,104(r1)
lfs f25,108(r1)
lfs f26,112(r1)
lfs f27,116(r1)
lfs f28,120(r1)
lfs f29,124(r1)
lfs f30,128(r1)
lfs f31,132(r1)[/spoiler]
I was completely unaware. I just assumed that because it didn't freeze that it worked :S
I'll retest and let you know.
Quotefctiw temp3B,temp3B
stfs temp3B,0x18(basereg)
lwz tempf,0x18(basereg)
You need to use stfd instruction instead of stfs when you store an integer value in an FPR.
i.e.
fctiw temp3B,temp3B
stfd temp3B,0x18(basereg)
lwz tempf,0x1C(basereg)Edit:
I made a similar code. :)
http://www.youtube.com/watch?v=dJ_spSWihSs
[spoiler]/*-------------------------------------------------------------------------------*/
/*int --> float conversion using red zone
freg2 holds the constant 0x4330000080000000
*/
.macro fcfid freg1,freg2,reg1
stfd \freg2,-8(r1)
xoris \reg1,\reg1,0x8000
stw \reg1,-4(r1)
lfd \freg1,-8(r1)
fsub \freg1,\freg1,\freg2
.endm
/*-------------------------------------------------------------------------------*/
/*PUSH and POP*/
.macro stmfd from, to, offset,reg
stfd \from,\offset(\reg)
.if \to-\from
stmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
.macro lmfd from, to, offset,reg
lfd \from,\offset(\reg)
.if \to-\from
lmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
/*-------------------------------------------------------------------------------*/
/*Variables for stackframe*/
.set numGPRs,(31-12+1)
.set numFPRs,(_saveFPRs_end - _saveFPRs_start)/4
.set spaceToSave,((4 + ((4*numGPRs + 7)& ~7) + 8*numFPRs ) +7) & ~7
.set offsetforFPR,8 + ((4*numGPRs + 7) & ~7)
/*-------------------------------------------------------------------------------*/
/**/
.set PARAM_RATE,4
.set maxcolor,5
.set mincolor,6
.set H,7
.set S,8
.set L,9
.set RED,10
.set GREEN,11
.set BLUE,12
.set tmp1,13
.set tmp2,14
.set temp1,15
.set temp2,16
.set temp3,17
.set color,18
.set CONST_FPR,19
.set CONST_0.0, CONST_FPR+0
.set CONST_0.5, CONST_FPR+1
.set CONST_1.0, CONST_FPR+2
.set CONST_2.0, CONST_FPR+3
.set CONST_one_3rd, CONST_FPR+4
.set CONST_two_3rds, CONST_FPR+5
.set CONST_3.0 , CONST_FPR+6
.set CONST_4.0, CONST_FPR+7
.set CONST_6.0, CONST_FPR+8
.set CONST_60.0, CONST_FPR+9
.set CONST_255.0, CONST_FPR+10
.set CONST_360.0, CONST_FPR+11
.set CONST_MAGIC, CONST_FPR+12
#GPRs
.set temp,11
.set anchor,12
.set red,14
.set green,15
.set blue,16
.set maxcolor_index,17
.set datap,18
.set savedLR,19
#indexes
.set color_index_RED,0
.set color_index_GREEN,1
.set color_index_BLUE,2
.set address,0x813454A0
/*-------------------------------------------------------------------------------*/
_stackframe:
stwu r1,-spaceToSave(r1) #allocate room for r14-r31
stmw r12,8(r1) #load r14-r31 into stackframe
_saveFPRs_start:
stmfd 4,31,offsetforFPR,1
_saveFPRs_end:
mflr savedLR
bl _const_data_end
_const_data:
.float 0.0
.float 0.5
.float 1.0
.float 2.0
.float 3.0
.float 0.33333333
.float 0.66666666
.float 4.0
.float 6.0
.float 60.0
.float 255.0
.float 360.0
.double 4503601774854144
.float 0.125
.long address
_const_data_end:
mflr anchor
lfs CONST_0.0,0(anchor)
lfs CONST_0.5,4(anchor)
lfs CONST_1.0,8(anchor)
lfs CONST_2.0,12(anchor)
lfs CONST_3.0,16(anchor)
lfs CONST_one_3rd,20(anchor)
lfs CONST_two_3rds,24(anchor)
lfs CONST_4.0,28(anchor)
lfs CONST_6.0,32(anchor)
lfs CONST_60.0,36(anchor)
lfs CONST_255.0,40(anchor)
lfs CONST_360.0,44(anchor)
lfd CONST_MAGIC,48(anchor)
lfs PARAM_RATE,56(anchor)
lwz datap,60(anchor)
lbz red,0(datap)
fcfid RED,CONST_MAGIC,red
fdiv RED,RED,CONST_255.0
lbz green,1(datap)
fcfid GREEN,CONST_MAGIC,green
fdiv GREEN,GREEN,CONST_255.0
lbz blue,2(datap)
fcfid BLUE,CONST_MAGIC,blue
fdiv BLUE,BLUE,CONST_255.0
/*-------------------------------------------------------------------------------*/
#RGB - HSL
#Convert the RBG values to the range 0-1
/*
Example: from the video colors page, colorbar red has R=83%, B=7%, G=7%, or in this scale, R=.83, B=.07, G=.07
Find min and max values of R, B, G
In the example, maxcolor = .83, mincolor=.07
*/
fmr maxcolor,RED
fmr mincolor,RED
li maxcolor_index,color_index_RED
fcmpu cr0,maxcolor,GREEN
bgt- 0f
fmr maxcolor,GREEN
li maxcolor_index,color_index_GREEN
0:
fcmpu cr0,maxcolor,BLUE
bgt- 0f
fmr maxcolor,BLUE
li maxcolor_index,color_index_BLUE
0:
fcmpu cr0,mincolor,GREEN
blt- 0f
fmr mincolor,GREEN
0:
fcmpu cr0,mincolor,BLUE
blt- 0f
fmr mincolor,BLUE
0:
/*
L = (maxcolor + mincolor)/2
tmp1 = (maxcolor + mincolor)
*/
fadd tmp1,maxcolor,mincolor
fdiv L,tmp1,CONST_2.0
#For the example, L = (.83+.07)/2 = .45
/*
If the max and min colors are the same (ie the color is some kind of grey), S is defined to be 0, and H is undefined but in programs usually written as 0
*/
fcmpu cr0,maxcolor,mincolor
bne- 0f
fmr S,CONST_0.0
fmr H,CONST_0.0
0:
/*
Otherwise, test L.
If L < 0.5, S=(maxcolor-mincolor)/(maxcolor+mincolor)
If L >=0.5, S=(maxcolor-mincolor)/(2.0-maxcolor-mincolor)
tmp1 = (maxcolor - mincolor)
tmp2 = (maxcolor + mincolor) or tmp2 = (2.0 - (maxcolor + mincolor))
*/
fsub tmp1,maxcolor,mincolor
fadd tmp2,maxcolor,mincolor
fcmpu cr0,L,CONST_0.5
blt- 0f
fsub tmp2,CONST_2.0,tmp2
0:
fdiv S,tmp1,tmp2
#For the example, L=0.45 so S=(.83-.07)/(.83+.07) = .84
/*
If R=maxcolor, H = (G-B)/(maxcolor-mincolor)
If G=maxcolor, H = 2.0 + (B-R)/(maxcolor-mincolor)
If B=maxcolor, H = 4.0 + (R-G)/(maxcolor-mincolor)
tmp1 = (maxcolor-mincolor)
tmp2 = (X-Y) or (X-Y)/(maxcolor-mincolor)
*/
cmpwi maxcolor_index,color_index_RED
bne- 0f
fsub tmp2,GREEN,BLUE
fdiv H,tmp2,tmp1
b 1f
0:
cmpwi maxcolor_index,color_index_GREEN
bne- 0f
fsub tmp2,BLUE,RED
fdiv tmp2,tmp2,tmp1
fadd H,CONST_2.0,tmp2
b 1f
0:
_maxcolor_is_BLUE:
fsub tmp2,RED,GREEN
fdiv tmp2,tmp2,tmp1
fadd H,CONST_4.0,tmp2
1:
/*
For the example, R=maxcolor so H = (.07-.07)/(.83-.07) = 0
To use the scaling shown in the video color page, convert L and S back to percentages, and H into an angle in degrees (ie scale it from 0-360). From the computation in step 6, H will range from 0-6. RGB space is a cube, and HSL space is a double hexacone, where L is the principal diagonal of the RGB cube. Thus corners of the RGB cube; red, yellow, green, cyan, blue, and magenta, become the vertices of the HSL hexagon. Then the value 0-6 for H tells you which section of the hexgon you are in. H is most commonly given as in degrees, so to convert
H = H*60.0
If H is negative, add 360 to complete the conversion.
*/
fmul H,H,CONST_60.0
fcmpu cr0,H,CONST_0.0
bge- 0f
fadd H,H,CONST_360.0
0:
/*-------------------------------------------------------------------------------*/
fadd H,H,PARAM_RATE
fcmpu cr0,H,CONST_360.0
ble- 0f
fsub H,H,CONST_360.0
0:
/*-------------------------------------------------------------------------------*/
#HSL - RGB
/*
If S=0, define R, G, and B all to L
*/
fcmpu cr0,S,CONST_0.0
bne- 0f
fmr RED,L
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
stb red,1(datap)
stb red,2(datap)
b _return
0:
/*
Otherwise, test L.
If L < 0.5, temp2=L*(1.0+S)
If L >= 0.5, temp2=L+S - L*S
tmp1 = (1.0+S)
tmp1 = (L+S)
tmp2 = (L*S)
*/
fcmpu cr0,L,CONST_0.5
bge- 0f
fadd tmp1,S,CONST_1.0
fmul temp2,L,tmp1
b 1f
0:
fadd tmp1,L,S
fmul tmp2,L,S
fsub temp2,tmp1,tmp2
1:
/*
In the colorbar example for colorbar green, H=120, L=52, S=79, so converting to the range 0-1, L=.52, so
temp2=(.52+.79) - (.52*.79) = .899
*/
/*
temp1 = 2.0*L - temp2
In the example, temp1 = 2.0*.52 - .899 = .141
*/
fmul tmp1,CONST_2.0,L
fsub temp1,tmp1,temp2
/*
Convert H to the range 0-1
In the example, H=120/360 = .33
For each of R, G, B, compute another temporary value, temp3, as follows:
*/
fdiv H,H,CONST_360.0
/*
for R, temp3=H+1.0/3.0
for G, temp3=H
for B, temp3=H-1.0/3.0
*/
fadd temp3,H,CONST_one_3rd
bl _calculate_color
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
fmr temp3,H
bl _calculate_color
fmul GREEN,color,CONST_255.0
fctiw GREEN,GREEN
stfd GREEN,-8(r1)
lwz green,-4(r1)
stb green,1(datap)
fsub temp3,H,CONST_one_3rd
bl _calculate_color
fmul BLUE,color,CONST_255.0
fctiw BLUE,BLUE
stfd BLUE,-8(r1)
lwz blue,-4(r1)
stb blue,2(datap)
b _return
/*-----------------------------------------------------------------------------------------------------------*/
/*
if temp3 < 0, temp3 = temp3 + 1.0
if temp3 > 1, temp3 = temp3 - 1.0
In the example, Rtemp3=.33+.33 = .66, Gtemp3=.33, Btemp3=.33-.33=0
*/
_calculate_color:
fcmpu cr0,temp3,CONST_0.0
bge- 0f
fadd temp3,temp3,CONST_1.0
0:
fcmpu cr0,temp3,CONST_1.0
ble- 0f
fsub temp3,temp3,CONST_1.0
0:
/*
For each of R, G, B, do the following test:
If 6.0*temp3 < 1, color=temp1+(temp2-temp1)*6.0*temp3
tmp1 = 6.0*temp3
tmp1 = (temp2-temp1)
tmp1 = (temp2-temp1)*6.0
tmp1 = (temp2-temp1)*6.0*temp3
*/
fmul tmp1,temp3,CONST_6.0
fcmpu cr0,tmp1,CONST_1.0
bge- 0f
fsub tmp1,temp2,temp1
fmul tmp1,tmp1,CONST_6.0
fmul tmp1,tmp1,temp3
fadd color,temp1,tmp1
blr
0:
/*
Else if 2.0*temp3 < 1, color=temp2
*/
fmul tmp1,temp3,CONST_2.0
fcmpu cr0,tmp1,CONST_1.0
bge- 0f
fmr color,temp2
blr
0:
/*
Else if 3.0*temp3 < 2, color=temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0
tmp1 = (temp2-temp1)
tmp2 = (2.0/3.0)-temp3
tmp1 = (temp2-temp1) * (2.0/3.0)-temp3
tmp1 = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0
color = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0 +temp1
*/
fmul tmp1,temp3,CONST_3.0
fcmpu cr0,tmp1,CONST_2.0
bge- 0f
fsub tmp1,temp2,temp1
fsub tmp2,CONST_two_3rds,temp3
fmul tmp1,tmp1,tmp2
fmul tmp1,tmp1,CONST_6.0
fadd color,tmp1,temp1
blr
0:
/*
Else color=temp1
*/
fmr color,temp1
blr
/*
In the example,
3.0*Rtemp3 < 2 so R=.141+(.899-.141)*((2.0/3.0-.66)*6.0=.141
2.0*Gtemp3 < 1 so G=.899
6.0*Btemp3 < 1 so B=.141+(.899-.141)*6.0*0=.141
Scale back to the range 0-100 to use the scaling shown in the video color page
For the example, R=14, G=90, B=14
*/
/*-----------------------------------------------------------------------------------------------------------*/
_return:
mtlr savedLR
lmw r12,8(r1)
lmfd 4,31,offsetforFPR,1
addi r1,r1,spaceToSave
/*-----------------------------------------------------------------------------------------------------------*/
[/spoiler]
Absolutely epic. You made your own function! I'm beginning to think I should make a sticky post that just links to all of your examples. There is so much to learn.
I have two questions
1) The "red zone". Negative stack frame index? Is there a place where this behavior is defined?
2) What are the 0: and 0f branch labels? I can infer their purpose - to avoid coming up with unnecessary branch labels - but is there any more meaning to them? Is there one for branches backward?
The red zone is a memory area that can be used in a leaf function. The size of the area is 0xE0 bytes.
I often use this area for a temporary storage.
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/100-32-bit_PowerPC_Function_Calling_Conventions/32bitPowerPC.html
A label that has a single number as its name is a local label. You can use the same labels name over and over.
I use these labels because I don't think it's appropriate to always give labels specific names.
"b 0f" jumps to the label 0 that appears after the branch, and "b 0b" jumps to the label 0 that appears before the branch.
http://sourceware.org/binutils/docs-2.18/as/Symbol-Names.html#Symbol-Names
gah Y.S. why are you so smart ._.
also you should get a github. Would be nice to see what crazy stuff you're working on. i know i would have liked to see your progress on what I had failed at doing D:
@hetoan2
Your original idea of color cycles was attractive enough for me to write the code for myself.
I just wanted to write all the codes I had in mind while I can, to share what I've learnt in past 10 years.
----
Modified the code a little so that it can be used in C2 codes :-*
You can make a color changing code for any game that uses RGB colors.
[spoiler].macro lwi reg, value
lis \reg, \value@h
ori \reg, \reg, \value@l
.endm
/*
int --> float conversion using red zone
freg2 holds the constant 0x4330000080000000
*/
.macro fcfid freg1,freg2,reg1
stfd \freg2,-8(r1)
xoris \reg1,\reg1,0x8000
stw \reg1,-4(r1)
lfd \freg1,-8(r1)
fsub \freg1,\freg1,\freg2
.endm
/*
PUSH and POP
*/
.macro stmfd from, to, offset,reg
stfd \from,\offset(\reg)
.if \to-\from
stmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
.macro lmfd from, to, offset,reg
lfd \from,\offset(\reg)
.if \to-\from
lmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
/*
Variables for stackframe
*/
.set numGPRs,(31-12+1)
.set numFPRs,(_saveFPRs_end - _saveFPRs_start)/4
.set spaceToSave,((4 + ((4*numGPRs + 7)& ~7) + 8*numFPRs ) +7) & ~7
.set offsetforFPR,8 + ((4*numGPRs + 7) & ~7)
# FPRs
.set PARAM_RATE,4
.set maxcolor,5
.set mincolor,6
.set H,7
.set S,8
.set L,9
.set RED,10
.set GREEN,11
.set BLUE,12
.set tmp1,13
.set tmp2,14
.set temp1,15
.set temp2,16
.set temp3,17
.set color,18
.set CONST_0.0, 19
.set CONST_0.5, 20
.set CONST_1.0, 21
.set CONST_2.0, 22
.set CONST_one_3rd, 23
.set CONST_two_3rds, 24
.set CONST_3.0, 25
.set CONST_4.0, 26
.set CONST_6.0, 27
.set CONST_60.0, 28
.set CONST_255.0, 29
.set CONST_360.0, 30
.set CONST_MAGIC, 31
# GPRs
.set anchor,12
.set red,14
.set green,15
.set blue,16
.set maxcolor_index,17
.set mincolor_index,18
.set datap,19
.set savedLR,20
#indexes
.set color_index_RED,0
.set color_index_GREEN,1
.set color_index_BLUE,2
/*-------------------------------------------------------------------------------*/
_stackframe:
stwu r1,-spaceToSave(r1)
stmw r12,8(r1)
_saveFPRs_start:
stmfd 4,31,offsetforFPR,1
_saveFPRs_end:
mflr savedLR
/*
Set a pointer to the RGB data
Edit if needed
*/
addi datap,r27,1392
bl _const_data_end
_const_data:
.float 0.0
.float 0.5
.float 1.0
.float 2.0
.float 3.0
.float 0.33333333
.float 0.66666666
.float 4.0
.float 6.0
.float 60.0
.float 255.0
.float 360.0
.double 4503601774854144
/*
Color changing rate
Edit if needed
*/
.float 0.125
_const_data_end:
mflr anchor
lfs CONST_0.0,0(anchor)
lfs CONST_0.5,4(anchor)
lfs CONST_1.0,8(anchor)
lfs CONST_2.0,12(anchor)
lfs CONST_3.0,16(anchor)
lfs CONST_one_3rd,20(anchor)
lfs CONST_two_3rds,24(anchor)
lfs CONST_4.0,28(anchor)
lfs CONST_6.0,32(anchor)
lfs CONST_60.0,36(anchor)
lfs CONST_255.0,40(anchor)
lfs CONST_360.0,44(anchor)
lfd CONST_MAGIC,48(anchor)
lfs PARAM_RATE,56(anchor)
# Convert the RBG values to the range 0-1
lbz red,0(datap)
fcfid RED,CONST_MAGIC,red
fdiv RED,RED,CONST_255.0
lbz green,1(datap)
fcfid GREEN,CONST_MAGIC,green
fdiv GREEN,GREEN,CONST_255.0
lbz blue,2(datap)
fcfid BLUE,CONST_MAGIC,blue
fdiv BLUE,BLUE,CONST_255.0
/*-------------------------------------------------------------------------------*/
#RGB - HSL
/*
Find min and max values of R, B, G
*/
fmr maxcolor,RED
fmr mincolor,RED
li maxcolor_index,color_index_RED
li mincolor_index,color_index_RED
fcmpo cr0,maxcolor,GREEN
bgt- 0f
fmr maxcolor,GREEN
li maxcolor_index,color_index_GREEN
0:
fcmpo cr0,maxcolor,BLUE
bgt- 0f
fmr maxcolor,BLUE
li maxcolor_index,color_index_BLUE
0:
fcmpo cr0,mincolor,GREEN
blt- 0f
fmr mincolor,GREEN
li mincolor_index,color_index_GREEN
0:
fcmpo cr0,mincolor,BLUE
blt- 0f
fmr mincolor,BLUE
li mincolor_index,color_index_BLUE
0:
/*
L = (maxcolor + mincolor)/2
tmp1 = (maxcolor + mincolor)
*/
fadd tmp1,maxcolor,mincolor
fdiv L,tmp1,CONST_2.0
/*
If the max and min colors are the same (ie the color is some kind of grey), S is defined to be 0, and H is undefined but in programs usually written as 0
*/
cmpw maxcolor_index,mincolor_index
bne- 0f
fmr S,CONST_0.0
fmr H,CONST_0.0
b _HSL2RGB
0:
/*
Otherwise, test L.
If L < 0.5, S=(maxcolor-mincolor)/(maxcolor+mincolor)
If L >=0.5, S=(maxcolor-mincolor)/(2.0-maxcolor-mincolor)
tmp1 = (maxcolor - mincolor)
tmp2 = (maxcolor + mincolor) or tmp2 = (2.0 - (maxcolor + mincolor))
*/
fsub tmp1,maxcolor,mincolor
fadd tmp2,maxcolor,mincolor
fcmpo cr0,L,CONST_0.5
blt- 0f
fsub tmp2,CONST_2.0,tmp2
0:
fdiv S,tmp1,tmp2
/*
If R=maxcolor, H = (G-B)/(maxcolor-mincolor)
If G=maxcolor, H = 2.0 + (B-R)/(maxcolor-mincolor)
If B=maxcolor, H = 4.0 + (R-G)/(maxcolor-mincolor)
tmp1 = (maxcolor-mincolor)
tmp2 = (X-Y) or (X-Y)/(maxcolor-mincolor)
*/
cmpwi maxcolor_index,color_index_RED
bne- 0f
fsub tmp2,GREEN,BLUE
fdiv H,tmp2,tmp1
b 1f
0:
cmpwi maxcolor_index,color_index_GREEN
bne- 0f
fsub tmp2,BLUE,RED
fdiv tmp2,tmp2,tmp1
fadd H,CONST_2.0,tmp2
b 1f
0:
_maxcolor_is_BLUE:
fsub tmp2,RED,GREEN
fdiv tmp2,tmp2,tmp1
fadd H,CONST_4.0,tmp2
1:
/*
To use the scaling shown in the video color page, convert L and S back to percentages, and H into an angle in degrees (ie scale it from 0-360). From the computation in step 6, H will range from 0-6. RGB space is a cube, and HSL space is a double hexacone, where L is the principal diagonal of the RGB cube. Thus corners of the RGB cube; red, yellow, green, cyan, blue, and magenta, become the vertices of the HSL hexagon. Then the value 0-6 for H tells you which section of the hexgon you are in. H is most commonly given as in degrees, so to convert
H = H*60.0
*/
fmul H,H,CONST_60.0
fcmpo cr0,H,CONST_0.0
bge- 0f
fadd H,H,CONST_360.0
0:
_update_hue:
fadd H,H,PARAM_RATE
fcmpo cr0,H,CONST_360.0
ble- 0f
fmr H,CONST_0.0
0:
/*---HSL - RGB---*/
_HSL2RGB:
/*
If S=0, define R, G, and B all to L
*/
fcmpo cr0,S,CONST_0.0
bne- 0f
fmr RED,L
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
stb red,1(datap)
stb red,2(datap)
b _return
0:
/*
Otherwise, test L.
If L < 0.5, temp2=L*(1.0+S)
If L >= 0.5, temp2=L+S - L*S
tmp1 = (1.0+S)
tmp1 = (L+S)
tmp2 = (L*S)
*/
fcmpo cr0,L,CONST_0.5
bge- 0f
fadd tmp1,S,CONST_1.0
fmul temp2,L,tmp1
b 1f
0:
fadd tmp1,L,S
fmul tmp2,L,S
fsub temp2,tmp1,tmp2
1:
/*
temp1 = 2.0*L - temp2
*/
fmul tmp1,CONST_2.0,L
fsub temp1,tmp1,temp2
/*
Convert H to the range 0-1
For each of R, G, B, compute another temporary value, temp3, as follows:
for R, temp3=H+1.0/3.0
for G, temp3=H
for B, temp3=H-1.0/3.0
*/
fdiv H,H,CONST_360.0
fadd temp3,H,CONST_one_3rd
bl _calculate_color
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
fmr temp3,H
bl _calculate_color
fmul GREEN,color,CONST_255.0
fctiw GREEN,GREEN
stfd GREEN,-8(r1)
lwz green,-4(r1)
stb green,1(datap)
fsub temp3,H,CONST_one_3rd
bl _calculate_color
fmul BLUE,color,CONST_255.0
fctiw BLUE,BLUE
stfd BLUE,-8(r1)
lwz blue,-4(r1)
stb blue,2(datap)
b _return
/*-----------------------------------------------------------------------------------------------------------*/
_calculate_color:
/*
if temp3 < 0, temp3 = temp3 + 1.0
if temp3 > 1, temp3 = temp3 - 1.0
*/
fcmpo cr0,temp3,CONST_1.0
ble- 0f
fsub temp3,temp3,CONST_1.0
0:
fcmpo cr0,temp3,CONST_0.0
bge- 0f
fadd temp3,temp3,CONST_1.0
0:
/*
For each of R, G, B, do the following test:
If 6.0*temp3 < 1, color=temp1+(temp2-temp1)*6.0*temp3
tmp1 = 6.0*temp3
tmp1 = (temp2-temp1)
tmp1 = (temp2-temp1)*6.0
tmp1 = (temp2-temp1)*6.0*temp3
*/
fmul tmp1,temp3,CONST_6.0
fcmpo cr0,tmp1,CONST_1.0
bge- 0f
fsub tmp1,temp2,temp1
fmul tmp1,tmp1,CONST_6.0
fmul tmp1,tmp1,temp3
fadd color,temp1,tmp1
blr
0:
/*
Else if 2.0*temp3 < 1, color=temp2
*/
fmul tmp1,temp3,CONST_2.0
fcmpo cr0,tmp1,CONST_1.0
bge- 0f
fmr color,temp2
blr
0:
/*
Else if 3.0*temp3 < 2, color=temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0
tmp1 = (temp2-temp1)
tmp2 = (2.0/3.0)-temp3
tmp1 = (temp2-temp1) * ((2.0/3.0)-temp3)
tmp1 = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0
color = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0 +temp1
*/
fmul tmp1,temp3,CONST_3.0
fcmpo cr0,tmp1,CONST_2.0
bge- 0f
fsub tmp1,temp2,temp1
fsub tmp2,CONST_two_3rds,temp3
fmul tmp1,tmp1,tmp2
fmul tmp1,tmp1,CONST_6.0
fadd color,tmp1,temp1
blr
0:
/*
Else color=temp1
*/
fmr color,temp1
blr
/*-----------------------------------------------------------------------------------------------------------*/
_return:
mtlr savedLR
lmw r12,8(r1)
lmfd 4,31,offsetforFPR,1
addi r1,r1,spaceToSave
# Edit if needed
_original_instruction:
lbz r0,1392(r27)[/spoiler]
Pikmin R9IJ01
Color Cycle for all Pikmin
C210F368 0000007B
9421FEC8 BD810008
D8810058 D8A10060
D8C10068 D8E10070
D9010078 D9210080
D9410088 D9610090
D9810098 D9A100A0
D9C100A8 D9E100B0
DA0100B8 DA2100C0
DA4100C8 DA6100D0
DA8100D8 DAA100E0
DAC100E8 DAE100F0
DB0100F8 DB210100
DB410108 DB610110
DB810118 DBA10120
DBC10128 DBE10130
7E8802A6 3A7B0570
48000041 00000000
3F000000 3F800000
40000000 40400000
3EAAAAAB 3F2AAAAB
40800000 40C00000
42700000 437F0000
43B40000 43300000
80000000 3E000000
7D8802A6 C26C0000
C28C0004 C2AC0008
C2CC000C C32C0010
C2EC0014 C30C0018
C34C001C C36C0020
C38C0024 C3AC0028
C3CC002C CBEC0030
C08C0038 89D30000
DBE1FFF8 6DCE8000
91C1FFFC C941FFF8
FD4AF828 FD4AE824
89F30001 DBE1FFF8
6DEF8000 91E1FFFC
C961FFF8 FD6BF828
FD6BE824 8A130002
DBE1FFF8 6E108000
9201FFFC C981FFF8
FD8CF828 FD8CE824
FCA05090 FCC05090
3A200000 3A400000
FC055840 4181000C
FCA05890 3A200001
FC056040 4181000C
FCA06090 3A200002
FC065840 4180000C
FCC05890 3A400001
FC066040 4180000C
FCC06090 3A400002
FDA5302A FD2DB024
7C119000 40820010
FD009890 FCE09890
48000074 FDA53028
FDC5302A FC09A040
41800008 FDD67028
FD0D7024 2C110000
40820010 FDCB6028
FCEE6824 48000028
2C110001 40820014
FDCC5028 FDCE6824
FCF6702A 48000010
FDCA5828 FDCE6824
FCFA702A FCE70732
FC079840 40800008
FCE7F02A FCE7202A
FC07F040 40810008
FCE09890 FC089840
40820028 FD404890
FD520772 FD40501C
D941FFF8 81C1FFFC
99D30000 99D30001
99D30002 48000100
FC09A040 40800010
FDA8A82A FE090372
48000010 FDA9402A
FDC90232 FE0D7028
FDB60272 FDED8028
FCE7F024 FE27B82A
48000055 FD520772
FD40501C D941FFF8
81C1FFFC 99D30000
FE203890 48000039
FD720772 FD60581C
D961FFF8 81E1FFFC
99F30001 FE27B828
4800001D FD920772
FD80601C D981FFF8
8201FFFC 9A130002
4800007C FC11A840
40810008 FE31A828
FC119840 40800008
FE31A82A FDB106F2
FC0DA840 40800018
FDB07828 FDAD06F2
FDAD0472 FE4F682A
4E800020 FDB105B2
FC0DA840 4080000C
FE408090 4E800020
FDB10672 FC0DB040
4080001C FDB07828
FDD88828 FDAD03B2
FDAD06F2 FE4D782A
4E800020 FE407890
4E800020 7E8803A6
B9810008 C8810058
C8A10060 C8C10068
C8E10070 C9010078
C9210080 C9410088
C9610090 C9810098
C9A100A0 C9C100A8
C9E100B0 CA0100B8
CA2100C0 CA4100C8
CA6100D0 CA8100D8
CAA100E0 CAC100E8
CAE100F0 CB0100F8
CB210100 CB410108
CB610110 CB810118
CBA10120 CBC10128
CBE10130 38210138
881B0570 00000000
get a github so i can fork your instructions for use in my own, I kinda feel guilty about posting it there when users really don't know where it came from (even if i credit in the source @_@)
https://github.com/hetoan2/Variable-Scoping/blob/master/variable-scope.asm
also it'd give you a chance to help out my coding w/o me asking :D
Got one:
https://github.com/Wyess/Color-Cycler-ASM/blob/master/color-cycler.asm
thanks :D will look forward to see what other stuff you put up ;)
http://wiird.l0nk.org/forum/index.php/topic,7879.msg67810.html#msg67810
crashes my game...
I used the read bp hook from the rgb address and put the original instruction at the end of the coding.
Anyways, using WiiRd codestypes, I got something similar to colour flashing:
A8000008 00000010 #counter (flash speed)
80000000 XXXXXXXX # Address
86010000 0000F000 # Add Value
E0000000 80008000 # Terminator
Did you modify the following part?
Quote/*
Set a pointer to the RGB data
Edit if needed
*/
addi datap,r27,1392
Quote from: Y.S. on January 22, 2012, 10:55:43 AM
Did you modify the following part?
Quote/*
Set a pointer to the RGB data
Edit if needed
*/
addi datap,r27,1392
no, what do I need to change there?
Let´s say, my address is 81123456 and the value is RRGGBBFF.
My hook is lwz r0, 8 (r26) (Address: 80123456).
How would I put it?
Thx man. ;D
Then, this will do the tirck;
addi datap,r26,8
This instruction sets the datap so that it points the RRGGBBFF.
still freezes.
[spoiler].macro lwi reg, value
lis \reg, \value@h
ori \reg, \reg, \value@l
.endm
/*
int --> float conversion using red zone
freg2 holds the constant 0x4330000080000000
*/
.macro fcfid freg1,freg2,reg1
stfd \freg2,-8(r1)
xoris \reg1,\reg1,0x8000
stw \reg1,-4(r1)
lfd \freg1,-8(r1)
fsub \freg1,\freg1,\freg2
.endm
/*
PUSH and POP
*/
.macro stmfd from, to, offset,reg
stfd \from,\offset(\reg)
.if \to-\from
stmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
.macro lmfd from, to, offset,reg
lfd \from,\offset(\reg)
.if \to-\from
lmfd "(\from+1)",\to, \offset+8,\reg
.endif
.endm
/*
Variables for stackframe
*/
.set numGPRs,(31-12+1)
.set numFPRs,(_saveFPRs_end - _saveFPRs_start)/4
.set spaceToSave,((4 + ((4*numGPRs + 7)& ~7) + 8*numFPRs ) +7) & ~7
.set offsetforFPR,8 + ((4*numGPRs + 7) & ~7)
# FPRs
.set PARAM_RATE,4
.set maxcolor,5
.set mincolor,6
.set H,7
.set S,8
.set L,9
.set RED,10
.set GREEN,11
.set BLUE,12
.set tmp1,13
.set tmp2,14
.set temp1,15
.set temp2,16
.set temp3,17
.set color,18
.set CONST_0.0, 19
.set CONST_0.5, 20
.set CONST_1.0, 21
.set CONST_2.0, 22
.set CONST_one_3rd, 23
.set CONST_two_3rds, 24
.set CONST_3.0, 25
.set CONST_4.0, 26
.set CONST_6.0, 27
.set CONST_60.0, 28
.set CONST_255.0, 29
.set CONST_360.0, 30
.set CONST_MAGIC, 31
# GPRs
.set anchor,12
.set red,14
.set green,15
.set blue,16
.set maxcolor_index,17
.set mincolor_index,18
.set datap,19
.set savedLR,20
#indexes
.set color_index_RED,0
.set color_index_GREEN,1
.set color_index_BLUE,2
/*-------------------------------------------------------------------------------*/
_stackframe:
stwu r1,-spaceToSave(r1)
stmw r12,8(r1)
_saveFPRs_start:
stmfd 4,31,offsetforFPR,1
_saveFPRs_end:
mflr savedLR
lwz r0,8(r3)
/*
Set a pointer to the RGB data
Edit if needed
*/
addi datap,r26,8
bl _const_data_end
_const_data:
.float 0.0
.float 0.5
.float 1.0
.float 2.0
.float 3.0
.float 0.33333333
.float 0.66666666
.float 4.0
.float 6.0
.float 60.0
.float 255.0
.float 360.0
.double 4503601774854144
/*
Color changing rate
Edit if needed
*/
.float 0.125
_const_data_end:
mflr anchor
lfs CONST_0.0,0(anchor)
lfs CONST_0.5,4(anchor)
lfs CONST_1.0,8(anchor)
lfs CONST_2.0,12(anchor)
lfs CONST_3.0,16(anchor)
lfs CONST_one_3rd,20(anchor)
lfs CONST_two_3rds,24(anchor)
lfs CONST_4.0,28(anchor)
lfs CONST_6.0,32(anchor)
lfs CONST_60.0,36(anchor)
lfs CONST_255.0,40(anchor)
lfs CONST_360.0,44(anchor)
lfd CONST_MAGIC,48(anchor)
lfs PARAM_RATE,56(anchor)
# Convert the RBG values to the range 0-1
lbz red,0(datap)
fcfid RED,CONST_MAGIC,red
fdiv RED,RED,CONST_255.0
lbz green,1(datap)
fcfid GREEN,CONST_MAGIC,green
fdiv GREEN,GREEN,CONST_255.0
lbz blue,2(datap)
fcfid BLUE,CONST_MAGIC,blue
fdiv BLUE,BLUE,CONST_255.0
/*-------------------------------------------------------------------------------*/
#RGB - HSL
/*
Find min and max values of R, B, G
*/
fmr maxcolor,RED
fmr mincolor,RED
li maxcolor_index,color_index_RED
li mincolor_index,color_index_RED
fcmpo cr0,maxcolor,GREEN
bgt- 0f
fmr maxcolor,GREEN
li maxcolor_index,color_index_GREEN
0:
fcmpo cr0,maxcolor,BLUE
bgt- 0f
fmr maxcolor,BLUE
li maxcolor_index,color_index_BLUE
0:
fcmpo cr0,mincolor,GREEN
blt- 0f
fmr mincolor,GREEN
li mincolor_index,color_index_GREEN
0:
fcmpo cr0,mincolor,BLUE
blt- 0f
fmr mincolor,BLUE
li mincolor_index,color_index_BLUE
0:
/*
L = (maxcolor + mincolor)/2
tmp1 = (maxcolor + mincolor)
*/
fadd tmp1,maxcolor,mincolor
fdiv L,tmp1,CONST_2.0
/*
If the max and min colors are the same (ie the color is some kind of grey), S is defined to be 0, and H is undefined but in programs usually written as 0
*/
cmpw maxcolor_index,mincolor_index
bne- 0f
fmr S,CONST_0.0
fmr H,CONST_0.0
b _HSL2RGB
0:
/*
Otherwise, test L.
If L < 0.5, S=(maxcolor-mincolor)/(maxcolor+mincolor)
If L >=0.5, S=(maxcolor-mincolor)/(2.0-maxcolor-mincolor)
tmp1 = (maxcolor - mincolor)
tmp2 = (maxcolor + mincolor) or tmp2 = (2.0 - (maxcolor + mincolor))
*/
fsub tmp1,maxcolor,mincolor
fadd tmp2,maxcolor,mincolor
fcmpo cr0,L,CONST_0.5
blt- 0f
fsub tmp2,CONST_2.0,tmp2
0:
fdiv S,tmp1,tmp2
/*
If R=maxcolor, H = (G-B)/(maxcolor-mincolor)
If G=maxcolor, H = 2.0 + (B-R)/(maxcolor-mincolor)
If B=maxcolor, H = 4.0 + (R-G)/(maxcolor-mincolor)
tmp1 = (maxcolor-mincolor)
tmp2 = (X-Y) or (X-Y)/(maxcolor-mincolor)
*/
cmpwi maxcolor_index,color_index_RED
bne- 0f
fsub tmp2,GREEN,BLUE
fdiv H,tmp2,tmp1
b 1f
0:
cmpwi maxcolor_index,color_index_GREEN
bne- 0f
fsub tmp2,BLUE,RED
fdiv tmp2,tmp2,tmp1
fadd H,CONST_2.0,tmp2
b 1f
0:
_maxcolor_is_BLUE:
fsub tmp2,RED,GREEN
fdiv tmp2,tmp2,tmp1
fadd H,CONST_4.0,tmp2
1:
/*
To use the scaling shown in the video color page, convert L and S back to percentages, and H into an angle in degrees (ie scale it from 0-360). From the computation in step 6, H will range from 0-6. RGB space is a cube, and HSL space is a double hexacone, where L is the principal diagonal of the RGB cube. Thus corners of the RGB cube; red, yellow, green, cyan, blue, and magenta, become the vertices of the HSL hexagon. Then the value 0-6 for H tells you which section of the hexgon you are in. H is most commonly given as in degrees, so to convert
H = H*60.0
*/
fmul H,H,CONST_60.0
fcmpo cr0,H,CONST_0.0
bge- 0f
fadd H,H,CONST_360.0
0:
_update_hue:
fadd H,H,PARAM_RATE
fcmpo cr0,H,CONST_360.0
ble- 0f
fmr H,CONST_0.0
0:
/*---HSL - RGB---*/
_HSL2RGB:
/*
If S=0, define R, G, and B all to L
*/
fcmpo cr0,S,CONST_0.0
bne- 0f
fmr RED,L
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
stb red,1(datap)
stb red,2(datap)
b _return
0:
/*
Otherwise, test L.
If L < 0.5, temp2=L*(1.0+S)
If L >= 0.5, temp2=L+S - L*S
tmp1 = (1.0+S)
tmp1 = (L+S)
tmp2 = (L*S)
*/
fcmpo cr0,L,CONST_0.5
bge- 0f
fadd tmp1,S,CONST_1.0
fmul temp2,L,tmp1
b 1f
0:
fadd tmp1,L,S
fmul tmp2,L,S
fsub temp2,tmp1,tmp2
1:
/*
temp1 = 2.0*L - temp2
*/
fmul tmp1,CONST_2.0,L
fsub temp1,tmp1,temp2
/*
Convert H to the range 0-1
For each of R, G, B, compute another temporary value, temp3, as follows:
for R, temp3=H+1.0/3.0
for G, temp3=H
for B, temp3=H-1.0/3.0
*/
fdiv H,H,CONST_360.0
fadd temp3,H,CONST_one_3rd
bl _calculate_color
fmul RED,color,CONST_255.0
fctiw RED,RED
stfd RED,-8(r1)
lwz red,-4(r1)
stb red,0(datap)
fmr temp3,H
bl _calculate_color
fmul GREEN,color,CONST_255.0
fctiw GREEN,GREEN
stfd GREEN,-8(r1)
lwz green,-4(r1)
stb green,1(datap)
fsub temp3,H,CONST_one_3rd
bl _calculate_color
fmul BLUE,color,CONST_255.0
fctiw BLUE,BLUE
stfd BLUE,-8(r1)
lwz blue,-4(r1)
stb blue,2(datap)
b _return
/*-----------------------------------------------------------------------------------------------------------*/
_calculate_color:
/*
if temp3 < 0, temp3 = temp3 + 1.0
if temp3 > 1, temp3 = temp3 - 1.0
*/
fcmpo cr0,temp3,CONST_1.0
ble- 0f
fsub temp3,temp3,CONST_1.0
0:
fcmpo cr0,temp3,CONST_0.0
bge- 0f
fadd temp3,temp3,CONST_1.0
0:
/*
For each of R, G, B, do the following test:
If 6.0*temp3 < 1, color=temp1+(temp2-temp1)*6.0*temp3
tmp1 = 6.0*temp3
tmp1 = (temp2-temp1)
tmp1 = (temp2-temp1)*6.0
tmp1 = (temp2-temp1)*6.0*temp3
*/
fmul tmp1,temp3,CONST_6.0
fcmpo cr0,tmp1,CONST_1.0
bge- 0f
fsub tmp1,temp2,temp1
fmul tmp1,tmp1,CONST_6.0
fmul tmp1,tmp1,temp3
fadd color,temp1,tmp1
blr
0:
/*
Else if 2.0*temp3 < 1, color=temp2
*/
fmul tmp1,temp3,CONST_2.0
fcmpo cr0,tmp1,CONST_1.0
bge- 0f
fmr color,temp2
blr
0:
/*
Else if 3.0*temp3 < 2, color=temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0
tmp1 = (temp2-temp1)
tmp2 = (2.0/3.0)-temp3
tmp1 = (temp2-temp1) * ((2.0/3.0)-temp3)
tmp1 = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0
color = (temp2-temp1) * ((2.0/3.0)-temp3) * 6.0 +temp1
*/
fmul tmp1,temp3,CONST_3.0
fcmpo cr0,tmp1,CONST_2.0
bge- 0f
fsub tmp1,temp2,temp1
fsub tmp2,CONST_two_3rds,temp3
fmul tmp1,tmp1,tmp2
fmul tmp1,tmp1,CONST_6.0
fadd color,tmp1,temp1
blr
0:
/*
Else color=temp1
*/
fmr color,temp1
blr
/*-----------------------------------------------------------------------------------------------------------*/
_return:
mtlr savedLR
lmw r12,8(r1)
lmfd 4,31,offsetforFPR,1
addi r1,r1,spaceToSave
# Edit if needed
_original_instruction:
lwz r0,8(r3)[/spoiler]Well, then I need to do it elsewise, if people can´t provide a working template...
[spoiler] CR:502409C0 XER:8000E510 CTR:0000000C DSIS:04000000
DAR:FFFF8C49 SRR0:800B26C8 SRR1:00001030 LR:00000000
r0:00000018 r1:80249C40 r2:80241D00 r3:04000080
r4:8015F7A0 r5:800B2750 r6:002635C0 r7:80144000
r8:80944B88 r9:9095161C r10:00000000 r11:00000002
r12:80944B88 r13:00000001 r14:00000000 r15:9095161C
r16:00000000 r17:00000002 r18:80249DA0 r19:40338000
r20:00000000 r21:00000000 r22:00000000 r23:00000000
r24:00000000 r25:00000000 r26:00000000 r27:00000000
r28:00000000 r29:00000018 r30:801D2338 r31:00000140
800B24A0: 9421FFE0 stwu r1,-32(r1)
800B24A4: 7C0802A6 mflr r0
800B24A8: 3C60CC00 lis r3,-13312
800B24AC: 90010024 stw r0,36(r1)
800B24B0: 93E1001C stw r31,28(r1)
800B24B4: 93C10018 stw r30,24(r1)
800B24B8: 7C9E2378 mr r30,r4
800B24BC: 93A10014 stw r29,20(r1)
800B24C0: 83E33000 lwz r31,12288(r3)
800B24C4: 80033004 lwz r0,12292(r3)
800B24C8: 57FF041D rlwinm. r31,r31,0,16,14
800B24CC: 4182000C beq- 0x800b24d8
800B24D0: 7FE00039 and. r0,r31,r0
800B24D4: 4082000C bne- 0x800b24e0
800B24D8: 7FC3F378 mr r3,r30
800B24DC: 4BFFB5C5 bl 0x800adaa0
800B24E0: 57E00631 rlwinm. r0,r31,0,24,24
800B24E4: 38000000 li r0,0
800B24E8: 41820048 beq- 0x800b2530
800B24EC: 3C60CC00 lis r3,-13312
800B24F0: A083401E lhz r4,16414(r3)
800B24F4: 548307FF rlwinm. r3,r4,0,31,31
800B24F8: 41820008 beq- 0x800b2500
800B24FC: 64008000 oris r0,r0,32768
800B2500: 548307BD rlwinm. r3,r4,0,30,30
800B2504: 41820008 beq- 0x800b250c
800B2508: 64004000 oris r0,r0,16384
800B250C: 5483077B rlwinm. r3,r4,0,29,29
800B2510: 41820008 beq- 0x800b2518
800B2514: 64002000 oris r0,r0,8192
800B2518: 54830739 rlwinm. r3,r4,0,28,28
800B251C: 41820008 beq- 0x800b2524
800B2520: 64001000 oris r0,r0,4096
800B2524: 548306F7 rlwinm. r3,r4,0,27,27
800B2528: 41820008 beq- 0x800b2530
800B252C: 64000800 oris r0,r0,2048
800B2530: 57E30673 rlwinm. r3,r31,0,25,25
800B2534: 41820030 beq- 0x800b2564
800B2538: 3C60CC00 lis r3,-13312
800B253C: A083500A lhz r4,20490(r3)
800B2540: 54830739 rlwinm. r3,r4,0,28,28
800B2544: 41820008 beq- 0x800b254c
800B2548: 64000400 oris r0,r0,1024
800B254C: 548306B5 rlwinm. r3,r4,0,26,26
800B2550: 41820008 beq- 0x800b2558
800B2554: 64000200 oris r0,r0,512
800B2558: 54830631 rlwinm. r3,r4,0,24,24
800B255C: 41820008 beq- 0x800b2564
800B2560: 64000100 oris r0,r0,256
800B2564: 57E306B5 rlwinm. r3,r31,0,26,26
800B2568: 41820018 beq- 0x800b2580
800B256C: 3C60CD00 lis r3,-13056
800B2570: 80636C00 lwz r3,27648(r3)
800B2574: 54630739 rlwinm. r3,r3,0,28,28
800B2578: 41820008 beq- 0x800b2580
800B257C: 64000080 oris r0,r0,128
800B2580: 57E306F7 rlwinm. r3,r31,0,27,27
800B2584: 4182007C beq- 0x800b2600
800B2588: 3C60CD00 lis r3,-13056
800B258C: 80836800 lwz r4,26624(r3)
800B2590: 548307BD rlwinm. r3,r4,0,30,30
800B2594: 41820008 beq- 0x800b259c
800B2598: 64000040 oris r0,r0,64
800B259C: 54830739 rlwinm. r3,r4,0,28,28
800B25A0: 41820008 beq- 0x800b25a8
800B25A4: 64000020 oris r0,r0,32
800B25A8: 54830529 rlwinm. r3,r4,0,20,20
800B25AC: 41820008 beq- 0x800b25b4
800B25B0: 64000010 oris r0,r0,16
800B25B4: 3C60CD00 lis r3,-13056
800B25B8: 80836814 lwz r4,26644(r3)
800B25BC: 548307BD rlwinm. r3,r4,0,30,30
800B25C0: 41820008 beq- 0x800b25c8
800B25C4: 64000008 oris r0,r0,8
800B25C8: 54830739 rlwinm. r3,r4,0,28,28
800B25CC: 41820008 beq- 0x800b25d4
800B25D0: 64000004 oris r0,r0,4
800B25D4: 54830529 rlwinm. r3,r4,0,20,20
800B25D8: 41820008 beq- 0x800b25e0
800B25DC: 64000002 oris r0,r0,2
800B25E0: 3C60CD00 lis r3,-13056
800B25E4: 80836828 lwz r4,26664(r3)
800B25E8: 548307BD rlwinm. r3,r4,0,30,30
800B25EC: 41820008 beq- 0x800b25f4
800B25F0: 64000001 oris r0,r0,1
800B25F4: 54830739 rlwinm. r3,r4,0,28,28
800B25F8: 41820008 beq- 0x800b2600
800B25FC: 60008000 ori r0,r0,32768
800B2600: 57E304A5 rlwinm. r3,r31,0,18,18
800B2604: 41820008 beq- 0x800b260c
800B2608: 60000020 ori r0,r0,32
800B260C: 57E304E7 rlwinm. r3,r31,0,19,19
800B2610: 41820008 beq- 0x800b2618
800B2614: 60000040 ori r0,r0,64
800B2618: 57E3056B rlwinm. r3,r31,0,21,21
800B261C: 41820008 beq- 0x800b2624
800B2620: 60001000 ori r0,r0,4096
800B2624: 57E305AD rlwinm. r3,r31,0,22,22
800B2628: 41820008 beq- 0x800b2630
800B262C: 60002000 ori r0,r0,8192
800B2630: 57E305EF rlwinm. r3,r31,0,23,23
800B2634: 41820008 beq- 0x800b263c
800B2638: 60000080 ori r0,r0,128
800B263C: 57E30739 rlwinm. r3,r31,0,28,28
800B2640: 41820008 beq- 0x800b2648
800B2644: 60000800 ori r0,r0,2048
800B2648: 57E3077B rlwinm. r3,r31,0,29,29
800B264C: 41820008 beq- 0x800b2654
800B2650: 60000400 ori r0,r0,1024
800B2654: 57E307BD rlwinm. r3,r31,0,30,30
800B2658: 41820008 beq- 0x800b2660
800B265C: 60000200 ori r0,r0,512
800B2660: 57E30529 rlwinm. r3,r31,0,20,20
800B2664: 41820008 beq- 0x800b266c
800B2668: 60004000 ori r0,r0,16384
800B266C: 57E307FF rlwinm. r3,r31,0,31,31
800B2670: 41820008 beq- 0x800b2678
800B2674: 60000100 ori r0,r0,256
800B2678: 57E30463 rlwinm. r3,r31,0,17,17
800B267C: 41820008 beq- 0x800b2684
800B2680: 60000010 ori r0,r0,16
800B2684: 3C608000 lis r3,-32768
800B2688: 808300C4 lwz r4,196(r3)
800B268C: 806300C8 lwz r3,200(r3)
800B2690: 7C831B78 or r3,r4,r3
800B2694: 7C031879 andc. r3,r0,r3
800B2698: 4182008C beq- 0x800b2724
800B269C: 3C808016 lis r4,-32746
800B26A0: 3884F790 subi r4,r4,2160
800B26A4: 60000000 nop
800B26A8: 80040000 lwz r0,0(r4)
800B26AC: 7C600039 and. r0,r3,r0
800B26B0: 41820010 beq- 0x800b26c0
800B26B4: 7C000034 cntlzw r0,r0
800B26B8: 7C1D0734 extsh r29,r0
800B26BC: 4800000C b 0x800b26c8
800B26C0: 38840004 addi r4,r4,4
800B26C4: 4BFFFFE4 b 0x800b26a8
800B26C8: 806D8C48 lwz r3,-29624(r13) # Crash
800B26CC: 57A0103A rlwinm r0,r29,2,0,29
800B26D0: 7FE3002E lwzx r31,r3,r0
800B26D4: 2C1F0000 cmpwi r31,0
800B26D8: 4182004C beq- 0x800b2724
800B26DC: 2C1D0004 cmpwi r29,4
800B26E0: 4081001C ble- 0x800b26fc
800B26E4: B3AD8C3C sth r29,-29636(r13)
800B26E8: 480051C9 bl 0x800b78b0
800B26EC: 908D8C44 stw r4,-29628(r13)
800B26F0: 906D8C40 stw r3,-29632(r13)
800B26F4: 801E0198 lwz r0,408(r30)
800B26F8: 900D8C38 stw r0,-29640(r13)
800B26FC: 480034E5 bl 0x800b5be0
800B2700: 7FECFB78 mr r12,r31
800B2704: 7FA3EB78 mr r3,r29
800B2708: 7FC4F378 mr r4,r30
800B270C: 7D8903A6 mtctr r12
800B2710: 4E800421 bctrl
800B2714: 4800350D bl 0x800b5c20
800B2718: 48003A29 bl 0x800b6140
800B271C: 7FC3F378 mr r3,r30
800B2720: 4BFFB381 bl 0x800adaa0
800B2724: 7FC3F378 mr r3,r30
800B2728: 4BFFB379 bl 0x800adaa0
800B272C: 80010024 lwz r0,36(r1)
800B2730: 83E1001C lwz r31,28(r1)
800B2734: 83C10018 lwz r30,24(r1)
800B2738: 83A10014 lwz r29,20(r1)
800B273C: 7C0803A6 mtlr r0
800B2740: 38210020 addi r1,r1,32
800B2744: 4E800020 blr
[/spoiler]
I guess this is related. MH3 uses 16 bit color for armor and probably hair and clothes. But the game does this
[spoiler](http://i46.servimg.com/u/f46/16/26/51/46/color10.jpg)[/spoiler]
I read about 16 bit color and they could be
Quote5 bits for red, 6 bits for green, and 5 bits for blue
It would probably make the most sense, but one bit for alpha might be cool.
It's just that I'm not sure how these colors work, and I want to put a rgb text display that would also allow you to do the rgb thing that MHFU had. You know. Scrolling the rgb colors instead of having this...this.