WiiRd forum

Wii & Gamecube Hacking => Wii Game hacking help => Topic started by: hetoan2 on February 13, 2011, 08:27:21 PM

Title: Color Cycler Assembly
Post by: hetoan2 on February 13, 2011, 08:27:21 PM
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 ._.
Title: Re: Color Cycler Assembly
Post by: hetoan2 on February 13, 2011, 09:01:45 PM
bump only minutes after posting because someone posted on another topic about 4 seconds after i posted this :\
Title: Re: Color Cycler Assembly
Post by: Bully@Wiiplaza on February 14, 2011, 01:09:01 AM
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
Title: Re: Color Cycler Assembly
Post by: hetoan2 on February 15, 2011, 01:22:03 AM
its not THAT challenging. besides, I think some people here could do it.
Title: Re: Color Cycler Assembly
Post by: megazig on February 15, 2011, 05:00:03 AM
Awwww, how come i don't hear about this fun stuff on irc
Title: Re: Color Cycler Assembly
Post by: hetoan2 on February 16, 2011, 12:13:13 AM
:S i like to bitch on IRC lol ._.

Title: Re: Color Cycler Assembly
Post by: hetoan2 on February 19, 2011, 12:46:40 PM
bump :\ i really want to figure this out pl0x

i know i'm a noob :S
Title: Re: Color Cycler Assembly
Post by: toonlink444 on February 21, 2011, 09:38:33 PM
YOU!!!! a NOOB!!!! Get real I'm a noob not you.
Title: Re: Color Cycler Assembly
Post by: hetoan2 on February 24, 2011, 12:10:36 AM
i meant for bumping my topic, however, i will do this again as i post this D:
Title: Re: Color Cycler Assembly
Post by: Y.S. on February 24, 2011, 09:11:26 AM
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]
Title: Re: Color Cycler Assembly
Post by: hetoan2 on March 02, 2011, 11:40:24 AM
I was completely unaware. I just assumed that because it didn't freeze that it worked :S

I'll retest and let you know.
Title: Re: Color Cycler Assembly
Post by: Y.S. on April 05, 2011, 05:16:00 AM
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]
Title: Re: Color Cycler Assembly
Post by: dcx2 on April 05, 2011, 01:33:08 PM
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?
Title: Re: Color Cycler Assembly
Post by: Y.S. on April 05, 2011, 03:27:05 PM
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
Title: Re: Color Cycler Assembly
Post by: hetoan2 on April 05, 2011, 08:59:04 PM
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:
Title: Re: Color Cycler Assembly
Post by: Y.S. on April 06, 2011, 09:10:38 AM
@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
Title: Re: Color Cycler Assembly
Post by: hetoan2 on April 06, 2011, 08:27:54 PM
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
Title: Re: Color Cycler Assembly
Post by: Y.S. on April 07, 2011, 03:20:51 AM
Got one:
https://github.com/Wyess/Color-Cycler-ASM/blob/master/color-cycler.asm
Title: Re: Color Cycler Assembly
Post by: hetoan2 on April 07, 2011, 08:33:42 PM
thanks :D will look forward to see what other stuff you put up ;)
Title: Re: Color Cycler Assembly
Post by: Bully@Wiiplaza on January 22, 2012, 10:50:19 AM
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
Title: Re: Color Cycler Assembly
Post by: 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
Title: Re: Color Cycler Assembly
Post by: Bully@Wiiplaza on January 22, 2012, 11:08:44 AM
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
Title: Re: Color Cycler Assembly
Post by: Y.S. on January 22, 2012, 11:14:41 AM
Then, this will do the tirck;
addi datap,r26,8

This instruction sets the datap so that it points the RRGGBBFF.
Title: Re: Color Cycler Assembly
Post by: Bully@Wiiplaza on January 22, 2012, 03:47:18 PM
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]
Title: Re: Color Cycler Assembly
Post by: Stuff on February 11, 2012, 08:31:01 PM
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.