static void trv_ray_ycaster34(FAR struct trv_raycast_s *result) { struct trv_rect_list_s *list; /* Points to the current P plane rectangle */ struct trv_rect_data_s *rect; /* Points to the rectangle data */ trv_coord_t rely; /* Relative position of the Y plane */ trv_coord_t absx; /* Absolute X position at rely given yaw */ trv_coord_t absz; /* Absolute Z position at rely given pitch */ trv_coord_t lastrely1 = -1; /* Last relative Y position processed */ trv_coord_t lastrely2 = -1; /* Last relative Y position processed */ int32_t dxdy; /* Rate of change of X wrt Y (double) */ int32_t dzdy; /* Rate of change of Z wrt Y (double) */ /* At a viewing angle of 180 degrees, no intersections with the line x = bXi * are possible! */ if (g_camera.yaw == ANGLE_180) { return; } /* Pre-calculate the rate of change of X and Z with respect to Y */ /* The negative inverted tangent is equal to the rate of change of X with * respect to the Y-axis. The cotangent is stored at double the the * "normal" scaling. */ dxdy = -g_cot_table(g_camera.yaw - ANGLE_180); /* Determine the rate of change of the Z with respect to Y. The tangent * is "double" precision; the cosecant is "double" precision. dzdy will * be retained as "double" precision. */ dzdy = qTOd(g_adj_tanpitch * ABS(g_csc_table[g_camera.yaw])); /* Look at every rectangle lying in a Y plane */ /* This logic should be improved at some point so that non-visible planes * are "pruned" from the list prior to ray casting! */ for (list = g_ray_yplane.tail; list; list = list->blink) { rect = &list->d; /* Search for a rectangle which lies "before" the current camera * position */ if (rect->plane < g_camera.y) { /* get the Y distance to the plane */ rely = g_camera.y - rect->plane; /* g_ray_yplane is an ordered list, if we have already hit something * closer, then we can abort the casting now. */ if (rely > result->ydist) { return; } /* Calculate the Y position at this relative X position. We can skip * this step if we are processing another rectangle at the same relx * distance. */ if (rely != lastrely1) { int32_t deltax; /* Scale == "triple" */ /* The dxdy is stored at double the"normal" scaling -- so deltax * is "triple" precision */ deltax = dxdy * ((int32_t) rely); absx = tTOs(deltax) + g_camera.x; /* back to "single" */ lastrely1 = rely; } /* Check if this X position intersects the rectangle */ if (absx >= rect->hstart && absx <= rect->hend) { /* The X position lies in the rectangle. Now, calculate the * Z position at this relative X position. We can skip this * step if we are processing another rectangle at the same * relx distance. */ if (rely != lastrely2) { int32_t deltaz; /* Scale == TRIPLE */ /* The dzdy is stored at double the"normal" scaling -- so * deltaz is "triple" precision */ deltaz = dzdy * ((int32_t) rely); absz = tTOs(deltaz) + g_camera.z; /* Back to single */ lastrely2 = rely; } /* Check if this Z position intersects the rectangle */ if (absz >= rect->vstart && absz <= rect->vend) { /* We've got a potential hit, let's see what it is */ /* Check if we just hit an ordinary opaque wall */ if (IS_NORMAL(rect)) { /* Yes..Save the parameters associated with the normal * wall hit */ result->rect = rect; result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT); result->xpos = absx; result->ypos = absz; result->xdist = ABS(absx - g_camera.x); result->ydist = rely; result->zdist = ABS(absz - g_camera.z); /* Terminate Y casting */ return; } else if (IS_DOOR(rect)) { /* Check if the door is in motion. */ if (!IS_MOVING_DOOR(rect)) { /* Save the parameters associated with the normal * door hit */ result->rect = rect; result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT); result->xpos = absx; result->ypos = absz; result->xdist = ABS(absx - g_camera.x); result->ydist = rely; result->zdist = ABS(absz - g_camera.z); /* Terminate Y casting */ return; } /* The door is in motion, the Z-position to see if we can * see under the door */ else if (absz > g_opendoor.zbottom) { /* Save the parameters associated with the moving * door hit */ result->rect = rect; result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT); result->xpos = absx; result->ypos = absz - g_opendoor.zdist; result->xdist = ABS(absx - g_camera.x); result->ydist = rely; result->zdist = ABS(absz - g_camera.z); /* Terminate Y casting */ return; } } /* Otherwise, it must be a transparent wall. We'll need to * make our decision based upon the pixel that we hit */ /* Check if the pixel at this location is visible */ else if (GET_BACK_PIXEL(rect, absx, absz) != INVISIBLE_PIXEL) { /* Its visible, save the parameters associated with the * transparent wall hit */ result->rect = rect; result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT); result->xpos = absx; result->ypos = absz; result->xdist = ABS(absx - g_camera.x); result->ydist = rely; result->zdist = ABS(absz - g_camera.z); /* Terminate Y casting */ return; } } } } } }
void key_press(uint8_t k) { uint8_t i; key[k].pressed = 0x80 | active_layer; if(current_dualrole_key != 255) { if(!dualrole_modifier_possible && IS_NORMAL(k) && WAS_TAPPABLE_LAYERSHIFT(current_dualrole_key) ) {//TODO do we need dualrole_modifier_possible ? for(i = 5; i > 0; i--) queue[i] = queue[i-1]; queue[0] = current_dualrole_key; active_layer = DISENGAGE_LAYER(current_dualrole_key); send(); for(i = 0; i < 6; i++) if(queue[i]==current_dualrole_key) break; for(i = i; i < 6; i++) queue[i] = queue[i+1]; send(); current_dualrole_key = 255; dualrole_tap_possible = false; dualrole_modifier_possible = false; dualrole_modifier_impossible_until_tick = 0; dualrole_tap_impossible_after_tick = 0; } } if(IS_TAPPABLE_MODIFIER(k)) { dualrole_tap_possible = true; dualrole_modifier_possible = false; dualrole_tap_impossible_after_tick = tick + LONGEST_TAP_DURATION; dualrole_modifier_impossible_until_tick = tick + SHORTEST_MODIFIER_DURATION; current_dualrole_key = k; mod_keys |= GET_TAPPABLE_MODIFIER(k); send(); } else if(IS_TAPPABLE_LAYERSHIFT(k)) { dualrole_tap_possible = true; dualrole_modifier_possible = false; dualrole_tap_impossible_after_tick = tick + LONGEST_TAP_DURATION; dualrole_modifier_impossible_until_tick = tick + SHORTEST_MODIFIER_DURATION; current_dualrole_key = k; active_layer = ENGAGE_LAYER(k); } else if(IS_LAYERLOCK(k)) { dualrole_tap_possible = true; dualrole_modifier_possible = false; current_dualrole_key = k; active_layer = ENGAGE_LAYER(k); } else if(IS_MODIFIER(k)) { mod_keys |= KEY(k); if(IS_MODDED(k)) { mod_keys |= ~GET_ADDITIONAL_MODIFIERS(k); } dualrole_tap_possible = false; send(); } else { dualrole_tap_possible = false; for(i = 5; i > 0; i--) queue[i] = queue[i-1]; queue[0] = k; send(); } }
static void trv_ray_xcaster14(FAR struct trv_raycast_s *result) { struct trv_rect_list_s *list; /* Points to the current X plane rectangle */ struct trv_rect_data_s *rect; /* Points to the rectangle data */ trv_coord_t relx; /* Relative position of the X plane */ trv_coord_t absy; /* Absolute Y position at relx given yaw */ trv_coord_t absz; /* Absolute Z position at relx given pitch */ trv_coord_t lastrelx1 = -1; /* Last relative X position processed */ trv_coord_t lastrelx2 = -1; /* Last relative X position processed */ int32_t dydx; /* Rate of change of Y wrt X (double) */ int32_t dzdx; /* Rate of change of Z wrt X (double) */ /* At a viewing angle of 270 degrees, no intersections with the g_ray_xplanes * are possible! */ if (g_camera.yaw == ANGLE_270) { return; } /* Pre-calculate the rate of change of Y and Z with respect to X */ /* The tangent is equal to the rate of change of Y with respect to the * X-axis. The tangent is stored at double the "normal" scaling. */ dydx = TAN(g_camera.yaw); /* Determine the rate of change of the Z with respect to X. The tangent is * "double" precision; the secant is "double" precision. dzdx will be * retained as "double" precision. */ dzdx = qTOd(g_adj_tanpitch * ABS(g_sec_table[g_camera.yaw])); /* Look at every rectangle lying in the X plane */ /* This logic should be improved at some point so that non-visible planes * are "pruned" from the list prior to ray casting! */ for (list = g_ray_xplane.head; list; list = list->flink) { rect = &list->d; /* Search for a rectangle which lies "beyond" the current camera * position */ if (rect->plane > g_camera.x) { /* get the X distance to the plane */ relx = rect->plane - g_camera.x; #if 0 /* g_ray_xplane is an ordered list, if we have already hit something * closer, then we can abort the casting now. */ if (relx > result->xdist) { return; } #endif /* Calculate the Y position at this relative X position. We can skip * this step if we are processing another rectangle at the same relx * distance. */ if (relx != lastrelx1) { int32_t deltay; /* Scale == "triple" */ /* The dydx is stored at double the"normal" scaling -- so * deltay is "triple" precision */ deltay = dydx * ((int32_t) relx); absy = tTOs(deltay) + g_camera.y; /* back to "single" */ lastrelx1 = relx; } /* Check if this Y position intersects the rectangle */ if (absy >= rect->hstart && absy <= rect->hend) { /* The Y position lies in the rectangle. Now, calculate the * theZ position at this relative X position. We can skip * this step if we are processing another rectangle at the * same relx distance. */ if (relx != lastrelx2) { int32_t deltaz; /* Scale == TRIPLE */ /* The dzdx is stored at double the"normal" scaling -- so * deltaz is "triple" precision */ deltaz = dzdx * ((int32_t) relx); absz = tTOs(deltaz) + g_camera.z; /* Back to single */ lastrelx2 = relx; } /* Check if this Z position intersects the rectangle */ if (absz >= rect->vstart && absz <= rect->vend) { /* We've got a potential hit, let's see what it is */ /* Check if we just hit an ordinary opaque wall */ if (IS_NORMAL(rect)) { /* Yes..Save the parameters associated with the normal * wall hit */ result->rect = rect; result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT); result->xpos = absy; result->ypos = absz; result->xdist = relx; result->ydist = ABS(absy - g_camera.y); result->zdist = ABS(absz - g_camera.z); /* Terminate X casting */ return; } else if (IS_DOOR(rect)) { /* Check if the door is in motion. */ if (!IS_MOVING_DOOR(rect)) { /* Save the parameters associated with the normal * door hit */ result->rect = rect; result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT); result->xpos = absy; result->ypos = absz; result->xdist = relx; result->ydist = ABS(absy - g_camera.y); result->zdist = ABS(absz - g_camera.z); /* Terminate X casting */ return; } /* The door is in motion, the Z-position to see if we can * see under the door */ else if (absz > g_opendoor.zbottom) { /* Save the parameters associated with the moving * door hit */ result->rect = rect; result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT); result->xpos = absy; result->ypos = absz - g_opendoor.zdist; result->xdist = relx; result->ydist = ABS(absy - g_camera.y); result->zdist = ABS(absz - g_camera.z); /* Terminate X casting */ return; } } /* Otherwise, it must be a transparent wall. We'll need to * make our decision based upon the pixel that we hit */ /* Check if the pixel at this location is visible */ else if (GET_FRONT_PIXEL(rect, absy, absz) != INVISIBLE_PIXEL) { /* Its visible, save the parameters associated with the * transparent wall hit */ result->rect = rect; result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT); result->xpos = absy; result->ypos = absz; result->xdist = relx; result->ydist = ABS(absy - g_camera.y); result->zdist = ABS(absz - g_camera.z); /* Terminate X casting */ return; } } } } } }