/** * Convert Hue Saturation Lightness value to RGB. * * \param hue Hue in degrees 0..360 * \param sat Saturation value in percent 0..100 * \param lit Lightness value in percent 0..100 * \param r red component * \param g green component * \param b blue component */ static void HSL_to_RGB(css_fixed hue, css_fixed sat, css_fixed lit, uint8_t *r, uint8_t *g, uint8_t *b) { css_fixed min_rgb, max_rgb, chroma; css_fixed relative_hue, scaled_hue, mid1, mid2; int sextant; #define ORGB(R, G, B) \ *r = FIXTOINT(FDIV(FMUL((R), F_255), F_100)); \ *g = FIXTOINT(FDIV(FMUL((G), F_255), F_100)); \ *b = FIXTOINT(FDIV(FMUL((B), F_255), F_100)) /* If saturation is zero there is no hue and r = g = b = lit */ if (sat == INTTOFIX(0)) { ORGB(lit, lit, lit); return; } /* Compute max(r,g,b) */ if (lit <= INTTOFIX(50)) { max_rgb = FDIV(FMUL(lit, FADD(sat, F_100)), F_100); } else { max_rgb = FDIV(FSUB(FMUL(FADD(lit, sat), F_100), FMUL(lit, sat)), F_100); } /* Compute min(r,g,b) */ min_rgb = FSUB(FMUL(lit, INTTOFIX(2)), max_rgb); /* We know that the value of at least one of the components is * max(r,g,b) and that the value of at least one of the other * components is min(r,g,b). * * We can determine which components have these values by * considering which the sextant of the hexcone the hue lies * in: * * Sextant: max(r,g,b): min(r,g,b): * * 0 r b * 1 g b * 2 g r * 3 b r * 4 b g * 5 r g * * Thus, we need only compute the value of the third component */ /* Chroma is the difference between min and max */ chroma = FSUB(max_rgb, min_rgb); /* Compute which sextant the hue lies in (truncates result) */ hue = FDIV(FMUL(hue, INTTOFIX(6)), F_360); sextant = FIXTOINT(hue); /* Compute offset of hue from start of sextant */ relative_hue = FSUB(hue, INTTOFIX(sextant)); /* Scale offset by chroma */ scaled_hue = FMUL(relative_hue, chroma); /* Compute potential values of the third colour component */ mid1 = FADD(min_rgb, scaled_hue); mid2 = FSUB(max_rgb, scaled_hue); /* Populate result */ switch (sextant) { case 0: ORGB(max_rgb, mid1, min_rgb); break; case 1: ORGB(mid2, max_rgb, min_rgb); break; case 2: ORGB(min_rgb, max_rgb, mid1); break; case 3: ORGB(min_rgb, mid2, max_rgb); break; case 4: ORGB(mid1, min_rgb, max_rgb); break; case 5: ORGB(max_rgb, min_rgb, mid2); break; } #undef ORGB }
int main(int argc, char *argv[]) { E_RT_init(argc, argv); JMP(begin); Label0: R005=ADD(R000,2); STI(R001, R000); R000=SUB(R000,1); MOVI(R000, R001); LDI(R005, R008); R005=ADD(R005,1); LDF(R005, F001); R005=ADD(R005,1); MOVIF(R008, F003); MOVIF(R008, F006); F005=FADD(F006,F001); MOVF(F005, F008); R010=ADD(R008,1); MOVI(R010, R011); MOVI(R010, R012); MOVIF(R008, F010); MOVF(F005, F011); while_1_start: JMPC(GT(1000, R008), while_1_begin); JMP(while_1_end); while_1_begin: MOVIF(R008, F013); MOVIF(R008, F014); F008=FADD(F014,F001); F001=FMUL(F001,2.0); R008=ADD(R008,100); JMP(while_1_start); while_1_end: PRTF(F008); PRTS(R007); MOVI(R008, R002); JMP(Label1); Label1: MOVI(R001, R000); R000=ADD(R000,1); LDI(R000, R001); R000=ADD(R000,1); LDI(R000, R004); R000=ADD(R000,2); JMPI(R004); eventLabel_a: INI(R010); INF(F013); STI(R010, R000); R000=SUB(R000,1); STF(F013, R000); R000=SUB(R000,1); STF(F013, R000); R000=SUB(R000,1); STI(R010, R000); R000=SUB(R000,1); MOVL(Label2, R004); STI(R004, R000); R000=SUB(R000,1); JMP(Label0); Label2: MOVI(R002, R006); R000=ADD(R000,1); LDF(R000, F013); R000=ADD(R000,1); LDI(R000, R010); JMP(EventMStart); begin: MOVI(10000, R000); MOVI(0, R006); MOVS("\n", R007); IN(R010); IN(R010); IN(R010); EventMStart: IN(R010); JMPC(GT(64, R010), EventMOut); JMPC(EQ(97, R010), eventLabel_a); JMP(EventMStart); EventMOut: PRTS("\nDone\n"); E_RT_exit(); return 0; }