/*This highlights the 4th dimension of the transformation matrix which is used for storing translations (shifts) in matricies so they can be combined with a matrix multiplication. Scroll bar works. The multiplication takes place in the Sprite3ZB routine. */ #define SLIDER_SPACING 20 #define SLIDER_RANGE 30 #define SLIDER_BORDER 2 class CSliderState { I64 s1, s2, s3; F64 arg1, arg2, scale; } s; U0 DrawCtrlSlider(CDC *dc, CCtrl *c) { CSliderState *s = c->state; dc->color = LTGREEN; GrRect(dc, c->left, c->top, SLIDER_SPACING * 4 + 3, SLIDER_SPACING * 2 + SLIDER_RANGE); dc->color = BROWN; GrRect(dc, c->left + SLIDER_BORDER, c->top + SLIDER_BORDER, SLIDER_SPACING * 4 + 3 - 2 * SLIDER_BORDER, SLIDER_SPACING * 2 + SLIDER_RANGE - 2 * SLIDER_BORDER); dc->color = BLACK; GrLine(dc, c->left + SLIDER_SPACING, c->top + SLIDER_SPACING, c->left + SLIDER_SPACING, c->top + SLIDER_SPACING + SLIDER_RANGE - 1); GrLine(dc, c->left + 2 * SLIDER_SPACING + 1, c->top + SLIDER_SPACING, c->left + 2 * SLIDER_SPACING + 1, c->top + SLIDER_SPACING + SLIDER_RANGE - 1); GrLine(dc, c->left + 3 * SLIDER_SPACING + 2, c->top + SLIDER_SPACING, c->left + 3 * SLIDER_SPACING + 2, c->top + SLIDER_SPACING + SLIDER_RANGE - 1); dc->color = LTGREEN; GrPrint(dc, c->left + SLIDER_SPACING - FONT_WIDTH / 2, c->top + SLIDER_SPACING + SLIDER_RANGE + 3, "%d", s->s1 * 10 / SLIDER_RANGE); GrPrint(dc, c->left + 2 * SLIDER_SPACING + 1 - FONT_WIDTH / 2, c->top + SLIDER_SPACING + SLIDER_RANGE + 3, "%d", s->s2 * 10 / SLIDER_RANGE); GrPrint(dc, c->left + 3 * SLIDER_SPACING + 2 - FONT_WIDTH / 2, c->top + SLIDER_SPACING + SLIDER_RANGE + 3, "%d", s->s3 * 10 / SLIDER_RANGE); GrRect(dc, c->left + SLIDER_SPACING - 3, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s1 - 2 , 7, 5); GrRect(dc, c->left + 2 * SLIDER_SPACING + 1 - 3, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s2 - 2, 7, 5); GrRect(dc, c->left + 3 * SLIDER_SPACING + 2 - 3, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s3 - 2, 7, 5); dc->color = GREEN; GrRect(dc, c->left + SLIDER_SPACING - 2, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s1 - 1 , 5, 3); GrRect(dc, c->left + 2 * SLIDER_SPACING + 1 - 2, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s2 - 1, 5, 3); GrRect(dc, c->left + 3 * SLIDER_SPACING + 2 - 2, c->top + SLIDER_SPACING + SLIDER_RANGE - 1 - s->s3 - 1, 5, 3); } U0 UpdateDerivedCtrlSlider(CCtrl *c) { CSliderState *s = c->state; c->left = c->win_task->pix_width / 2 - (SLIDER_SPACING * 4 + 3) / 2; c->right = c->left + SLIDER_SPACING * 4 + 3; c->top = c->win_task->pix_height / 2 - (SLIDER_SPACING * 2 + SLIDER_RANGE) / 2; c->bottom = c->top + SLIDER_SPACING * 2 + SLIDER_RANGE; s->s1 = ClampI64(s->s1, 0, SLIDER_RANGE - 1); s->s2 = ClampI64(s->s2, 0, SLIDER_RANGE - 1); s->s3 = ClampI64(s->s3, 1, SLIDER_RANGE - 1); s->arg1 = pi / 2.0 * s->s1 / SLIDER_RANGE; s->arg2 = 1.0 * (s->s2 - SLIDER_RANGE / 2) / SLIDER_RANGE; s->scale = 2.0 * s->s3 / SLIDER_RANGE; } U0 LeftClickSlider(CCtrl *c, I64 x, I64 y, Bool) { CSliderState *s = c->state; if (x < c->left + (c->right - c->left) / 3) s->s1 = SLIDER_RANGE - 1 - (y - (c->top + SLIDER_SPACING)); else if (x < c->left + 2 * (c->right - c->left) / 3) s->s2 = SLIDER_RANGE - 1 - (y - (c->top + SLIDER_SPACING)); else s->s3 = SLIDER_RANGE - 1 - (y - (c->top + SLIDER_SPACING)); if (c->update_derived_vals) (*c->update_derived_vals)(c); } CCtrl *SliderNew() { CCtrl *c = CAlloc(sizeof(CCtrl)); c->win_task = Fs; c->flags = CTRLF_SHOW | CTRLF_CAPTURE_LEFT_MS; c->type = CTRLT_GENERIC; c->state = &s; MemSet(&s, 0, sizeof(s)); c->draw_it = &DrawCtrlSlider; c->left_click = &LeftClickSlider; c->update_derived_vals = &UpdateDerivedCtrlSlider; QueueInsert(c, Fs->last_ctrl); TaskDerivedValsUpdate; return c; } U0 SliderDel(CCtrl *c) { QueueRemove(c); Free(c); } <1>/* Graphics Not Rendered in HTML */ #define MAP_HEIGHT 2048 #define MAP_WIDTH 2048 #define TREES_NUM 256 I64 tree_x[TREES_NUM], tree_y[TREES_NUM]; class MPCtrl { I64 mp_count; I64 r[16]; F64 a; } mp; I64 mp_not_done_flags; U0 MPDrawIt(CTask *task) { CDC *dc = DCAlias(gr.dc2, task); I64 i, lo = Gs->num * TREES_NUM / mp.mp_count, hi = (Gs->num + 1) * TREES_NUM / mp.mp_count; MemCopy(dc->r, mp.r, sizeof(I64) * 16); dc->flags |= DCF_TRANSFORMATION; for (i = lo; i < hi; i++) Sprite3ZB(dc, tree_x[i], tree_y[i], 0, <tree>, mp.a); DCDel(dc); LBtr(&mp_not_done_flags, Gs->num); } U0 DrawIt(CTask *task, CDC *dc) { I64 i, h, v; task->horz_scroll.min = -s.scale * MAP_HEIGHT * Sin(s.arg1); task->horz_scroll.max = s.scale * MAP_WIDTH * Cos(s.arg1) - task->pix_width; task->vert_scroll.min = 0; task->vert_scroll.max = s.scale * (MAP_HEIGHT * Cos(s.arg1) + MAP_WIDTH * Sin(s.arg1)) -task->pix_height; TaskDerivedValsUpdate(task); h = task->horz_scroll.pos; v = task->vert_scroll.pos; Mat4x4RotZ(dc->r, s.arg1); Mat4x4Scale(dc->r, s.scale); DCMat4x4Set(dc, dc->r); Mat4x4TranslationEqu(dc->r, -h, -v, 0); MemCopy(mp.r, dc->r, sizeof(I64) * 16); mp.a = s.arg2; mp_not_done_flags = 1 << mp_count - 1; for (i = 0; i < mp.mp_count; i++) JobQueue(&MPDrawIt, task, i); while (mp_not_done_flags) Yield; dc->flags |= DCF_TRANSFORMATION; dc->color = BROWN; dc->thick = 4; GrLine3(dc, 2, 2, 0, MAP_WIDTH - 3, 2, 0); GrLine3(dc, 2, MAP_HEIGHT - 3, 0, MAP_WIDTH - 3, MAP_HEIGHT - 3, 0); GrLine3(dc, 2, 2, 0, 2, MAP_HEIGHT - 3, 0); GrLine3(dc, MAP_WIDTH - 3, 2, 0, MAP_WIDTH - 3, MAP_HEIGHT - 3, 0); } U0 Init() { I64 i; for (i = 0; i < TREES_NUM; i++) { tree_x[i] = RandU16 % MAP_WIDTH; tree_y[i] = RandU16 % MAP_HEIGHT; } } U0 TransformDemo(I64 _mp_count=mp_count) { SettingsPush; //See SettingsPush Init; Fs->win_inhibit = WIG_TASK_DEFAULT - WIF_SELF_FOCUS - WIF_SELF_BORDER - WIF_SELF_GRAB_SCROLL - WIF_FOCUS_TASK_MENU - WIF_SELF_CTRLS; Fs->draw_it = &DrawIt; WinBorder(ON); DocCursor; DocClear; DocScroll; Fs->horz_scroll.pos = 0; Fs->vert_scroll.pos = 0; CCtrl *c = SliderNew; s.s1 = 0; s.s2 = SLIDER_RANGE / 2; s.s3 = SLIDER_RANGE / 2; MemSet(&mp, 0, sizeof(MPCtrl)); mp.mp_count = _mp_count; View; SliderDel(c); SettingsPop; //You might want to save the original state of the scroll bars. } TransformDemo;