Vector2 touch_joystick(TexHandle tex, uint layer, const RectF* back_src, const RectF* nub_src, const Vector2* pos) { assert(back_src); assert(nub_src); assert(pos); Color nub_color = COLOR_WHITE; float back_width = rectf_width(back_src); float back_height = rectf_height(back_src); // Draw static back RectF dest = { pos->x - back_width / 2.0f, pos->y - back_height / 2.0f, 0.0f, 0.0f }; video_draw_rect(tex, layer, back_src, &dest, COLOR_WHITE); Vector2 touch; if(!_get_touch(pos, joystick_area_radius, &touch)) { touch = vec2(0.0f, 0.0f); } else { touch = vec2_sub(touch, *pos); nub_color = pressed_color; } float nub_width = rectf_width(nub_src); float nub_height = rectf_width(nub_src); assert(feql(back_width, back_height) && feql(nub_width, nub_height)); float back_radius = back_width / 2.0f; float nub_radius = nub_width / 2.0f; float move_radius = back_radius - nub_radius; assert(move_radius > 4.0f); float offset_len = vec2_length(touch); if(offset_len > move_radius) { touch = vec2_scale(touch, move_radius / offset_len); offset_len = move_radius; nub_color = COLOR_WHITE; } // Draw nub dest.left = pos->x + touch.x - nub_width / 2.0f; dest.top = pos->y + touch.y - nub_height / 2.0f; video_draw_rect(tex, layer, nub_src, &dest, nub_color); if(offset_len < joystick_deadzone_radius) return vec2(0.0f, 0.0f); float norm_len = normalize(offset_len, joystick_deadzone_radius, move_radius); return vec2_scale(touch, norm_len / offset_len); }
void render_animated(vec3 color, vec2 offset, vec2 size, animation_state * animation){ UNUSED(size); u64 tex = get_animation_texture(animation->animation); if(tex == 0) return; animation_frame * frame = NULL; u64 * key = NULL; get_refs2_animation_frames(&animation->animation, &frame, &key, 1); if(frame == NULL || key == NULL) return; ASSERT(key[animation->frame] == animation->animation); while(animation->time > frame[animation->frame].time){ animation->time -= frame[animation->frame].time; animation->frame += 1; if(key[animation->frame] != animation->animation) animation->frame = 0; } texture_section sec[20]; u64 idx = 0; iter_texture_sections(tex, sec, 20, &idx); u64 ts = frame[animation->frame].section; i32 gltex = get_animation_gltexture(tex); vec2 render_size = vec2_scale(sec[ts].pixel_size, 3); vec2 center = vec2_add(offset, vec2_scale(size, 0.5)); vec2 offset2 = vec2_sub(center, vec2_scale(render_size, 0.5)); rect_render2(color, vec2_add(offset2, sec[ts].render_offset), render_size , gltex, sec[ts].uv_offset, sec[ts].uv_size); }
static bool powerup_help_render(float t) { if(t != 0.0f) game_update_empty(); UIElement* element = uidesc_get("powerup_help"); UIElement* text_elem2 = uidesc_get_child(element, "text2"); UIElement* text_elem3 = uidesc_get_child(element, "text3"); UIElement* star = uidesc_get_child(element, "star"); UIElement* item = uidesc_get_child(element, "item"); UIElement* button_quit = uidesc_get_child(element, "button_quit"); float state_alpha = 1.0f-fabsf(t); byte a = lrintf(255.0f * state_alpha); Color col = COLOR_RGBA(255, 255, 255, a); spr_draw("blue_shade", hud_layer-1, rectf(0.0f, 0.0f, v_width, v_height), col); static float xpos = 0.0f; static float inc = 600.0f; xpos = hud_scroll(xpos, inc, item_count, t); for(uint i = 0; i < item_count; ++i) { Vector2 off = vec2(xpos + i * inc, 0.0f); float d = normalize(fabsf(off.x), 0.0f, inc * (item_count-1)); float scroll_alpha = 1.0f / exp(PI*d); byte a2 = lrintf(255.0f * scroll_alpha * state_alpha); Color col2 = COLOR_RGBA(255, 255, 255, a2); // Star spr_draw_cntr_h(star->spr, hud_layer, vec2_add(off, star->vec2), time_s()/10.0f, 1.0f, col2); // Item const char* item_img = powerup_params[i].unlocked_spr; spr_draw_cntr(item_img, hud_layer, vec2_add(off, item->vec2), 0.0f, 1.0f, col2); // Description text const char* text3 = powerup_params[i].description; vfont_select(FONT_NAME, 32.0f); Vector2 half_size3 = vec2_scale(vfont_size(text3), 0.5f); vfont_draw(text3, hud_layer+1, vec2_add(off, vec2_sub(text_elem3->vec2,half_size3)), col2); // Item name const char* text2 = powerup_params[i].name; vfont_select(FONT_NAME, 48.0f); Vector2 half_size2 = vec2_scale(vfont_size(text2), 0.5f); vfont_draw(text2, hud_layer+1, vec2_add(off, vec2_sub(text_elem2->vec2,half_size2)), col2); } // Quit button if(hud_button(button_quit, col, t)) { malka_states_pop(); } return true; }
///////////////////////////// // Input_GetDir // // Reports the direction of the dpad. int Input_GetDir(vec2 dir) { float vlen; Uint8 buttons; int mx, my; float dlen; extern int _width, _height; // Get mouse state buttons = SDL_GetMouseState(&mx, &my); if (buttons) { // Use the mouse vec2_set(dir, mx - (_width / 2), my - (_height / 2.0f)); dlen = 1.0f / sqrtf(vec2_dot(dir, dir)); vec2_scale(dir, dir, dlen); return (1); } else { // Use the keyboar vec2_set(dir, 0.0f, 0.0f); if (Input_GetKey(InputKey_Up)) { dir[1] -= 1.0f; } if (Input_GetKey(InputKey_Down)) { dir[1] += 1.0f; } if (Input_GetKey(InputKey_Left)) { dir[0] -= 1.0f; } if (Input_GetKey(InputKey_Right)) { dir[0] += 1.0f; } vlen = vec2_dot(dir, dir); if (vlen > 0.0f) { vlen = sqrtf(vlen); vec2_scale(dir, dir, 1.0f / vlen); return (1); } else { return (0); } } }
int prim_rect_oriented(SDL_Renderer* renderer, Rect* rect, f32 rotation) { Vec2 corners[4]; Vec2 x = vec2_init(cosf(rotation), sinf(rotation)); Vec2 y = vec2_init(-sinf(rotation), cosf(rotation)); vec2_scale(&x, rect->width / 2.f, &x); vec2_scale(&y, rect->height / 2.f, &y); Vec2 center; center.x = rect->position.x + rect->width / 2.f; center.y = rect->position.y + rect->height / 2.f; for (u32 i = 0; i < 4; ++i) { vec2_copy_to(¢er, &corners[i]); } vec2_sub(&corners[0], &x, &corners[0]); vec2_sub(&corners[0], &y, &corners[0]); vec2_add(&corners[1], &x, &corners[1]); vec2_sub(&corners[1], &y, &corners[1]); vec2_add(&corners[2], &x, &corners[2]); vec2_add(&corners[2], &y, &corners[2]); vec2_sub(&corners[3], &x, &corners[3]); vec2_add(&corners[3], &y, &corners[3]); int result = 0; for (u32 i = 0; i < 4; ++i) { Vec2 c1 = corners[i]; Vec2 c2 = (i < 3) ? corners[i + 1] : corners[0]; result |= SDL_RenderDrawLine(renderer, (int)c1.x, (int)c1.y, (int)c2.x, (int)c2.y); } return result; }
// LINEAR BEZIER CURVES // =================================================== // B(t) = (1-t)P_0 + tP_1 void bezier2d_generate_linear ( vec2** pts, unsigned int count, unsigned int destct, vec2*** dest ) { *dest = malloc(sizeof(vec2*)*destct); double t = 0.0; double inc = (double)count/(double)destct; vec2 a, b, c; for(int i = 0, j=0; i < count-1; t += inc, j++) { if (t > 1.0) { t = t - 1.0; i++; } vec2_scale(&a, pts[i], 1.0-t); vec2_scale(&b, pts[i+1], t); vec2_add(&c, &a, &b); *dest[i] = vec2_copy(&c); } }
DArray _gen_edges(DArray points, DArray geometry) { DArray edges = darray_create(sizeof(Edge), 0); Vector2* points_vec2 = DARRAY_DATA_PTR(points, Vector2); for(uint i = 0; i < points.size; ++i) { for(uint j = 0; j < points.size; ++j) { if(i >= j) continue; float sqr_dist = _node_distance_sq(points_vec2[i], points_vec2[j]); if(sqr_dist <= max_edge_distance*max_edge_distance) { Edge n = {i, j}; Segment s = ai_shortest_path(points_vec2[i], points_vec2[j]); Segment s1, s2; bool split = ai_split_path(s, &s1, &s2); // Check for wall intersection Segment* geometry_s = DARRAY_DATA_PTR(geometry, Segment); bool intersects_arena = false; for(uint k = 0; k < geometry.size; ++k) { if(segment_intersect(s1, geometry_s[k], NULL)) { intersects_arena = true; break; } if(split && segment_intersect(s2, geometry_s[k], NULL)) { intersects_arena = true; break; } } // Check distance to walls at midpoint Vector2 midpoint = vec2_scale(vec2_add(s1.p1, s1.p2), 0.5f); if(ai_wall_distance(midpoint, geometry) < min_wall_distance) intersects_arena = true; if(!intersects_arena) darray_append(&edges, (void*)&n); } } } return edges; }
void gravity_system_update(GravitySystem* self) { GET_SYSTEM_COMPONENTS(self); for (u32 i = 0; i < components->count; ++i) { Entity entity = GET_ENTITY(i); GravityComponent* gravity = (GravityComponent*)GET_SYSTEM_COMPONENT(i); MovementComponent* movement = (MovementComponent*)GET_COMPONENT(entity, COMPONENT_MOVEMENT); REQUIRED_COMPONENTS(gravity, movement); Vec2 gravScale; vec2_copy_to(&gravity->gravAccel, &gravScale); vec2_scale(&gravScale, globals.time.delta, &gravScale); vec2_add(&movement->velocity, &gravScale, &movement->velocity); //printf("%f\n", movement->velocity.y); } }
static inline void gen_infinity(CPoint* out, float width, float angle, int segment_count) { CPoint path[13]; path[0]=CPointMake(53,23); path[1]=CPointMake(49,31); path[2]=CPointMake(39,47); path[3]=CPointMake(22,47); path[4]=CPointMake(6,47); path[5]=CPointMake(0,31); path[6]=CPointMake(0,23); path[7]=CPointMake(0,16); path[8]=CPointMake(5,0); path[9]=CPointMake(23,0); path[10]=CPointMake(39,0); path[11]=CPointMake(48,15); path[12]=CPointMake(52,21); int offset=0; int seg; for (seg=0; seg<=segment_count; seg++) { float tt = ((float)seg/(float)segment_count)*angle; int q=4; float tstep=1./q; int n = floor(tt/tstep); if (seg >= segment_count) { //n=n-1;//q-1; } //printf("n>%d\n", n); CPoint a = path[0+3*n];; CPoint p1 = path[1+3*n]; CPoint p2 = path[2+3*n]; CPoint b = path[3+3*n]; float t=(tt-tstep*n)*q; float nt = 1.0f - t; vec2 p = {a.x * nt * nt * nt + 3.0 * p1.x * nt * nt * t + 3.0 * p2.x * nt * t * t + b.x * t * t * t, a.y * nt * nt * nt + 3.0 * p1.y * nt * nt * t + 3.0 * p2.y * nt * t * t + b.y * t * t * t }; vec2 tangent = {-3.0 * a.x * nt * nt + 3.0 * p1.x * (1.0 - 4.0 * t + 3.0 * t * t) + 3.0 * p2.x * (2.0 * t - 3.0 * t * t) + 3.0 * b.x * t * t, -3.0 * a.y * nt * nt + 3.0 * p1.y * (1.0 - 4.0 * t + 3.0 * t * t) + 3.0 * p2.y * (2.0 * t - 3.0 * t * t) + 3.0 * b.y * t * t }; vec2 tan_norm = {-tangent[1], tangent[0]}; vec2 norm; vec2_norm(norm, tan_norm); vec2 v; vec2 norm_scaled; vec2_scale(norm_scaled, norm, +width/2.); vec2_add(v, p, norm_scaled); out[offset] = CPointMake(v[0], v[1]); offset++; vec2_scale(norm_scaled, norm, -width/2.); vec2_add(v, p, norm_scaled); out[offset] = CPointMake(v[0], v[1]); offset++; } //printf("infinity_q>%d", offset); }
void starship_fire(starship_t *starship, stage_t *stage) { if (starship->charge > FIRE_DRAIN) { entity_t *entity = (entity_t*)starship; int projectile_id = -1; if (entity->type == PLAYER) projectile_id = ((player_t*)starship)->player_id; uint16_t damage = 10 * (starship->weaponry_level + 1); projectile_t *projectile = malloc(sizeof(projectile_t)); projectile_init(projectile, projectile_id, damage, (movement_t){entity->movement.position, vec2_scale(entity->movement.orientation, PROJECTILE_SPEED), {0, 0}, entity->movement.orientation}); stage_add_entity(stage, (entity_t*)projectile); starship->charge -= FIRE_DRAIN; } }