void vframeArray::fill_in(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, const RegisterMap *reg_map, bool realloc_failures) { // Set owner first, it is used when adding monitor chunks _frame_size = frame_size; for(int i = 0; i < chunk->length(); i++) { element(i)->fill_in(chunk->at(i), realloc_failures); } // Copy registers for callee-saved registers if (reg_map != NULL) { for(int i = 0; i < RegisterMap::reg_count; i++) { #ifdef AMD64 // The register map has one entry for every int (32-bit value), so // 64-bit physical registers have two entries in the map, one for // each half. Ignore the high halves of 64-bit registers, just like // frame::oopmapreg_to_location does. // // [phh] FIXME: this is a temporary hack! This code *should* work // correctly w/o this hack, possibly by changing RegisterMap::pd_location // in frame_amd64.cpp and the values of the phantom high half registers // in amd64.ad. // if (VMReg::Name(i) < SharedInfo::stack0 && is_even(i)) { intptr_t* src = (intptr_t*) reg_map->location(VMRegImpl::as_VMReg(i)); _callee_registers[i] = src != NULL ? *src : NULL_WORD; // } else { // jint* src = (jint*) reg_map->location(VMReg::Name(i)); // _callee_registers[i] = src != NULL ? *src : NULL_WORD; // } #else jint* src = (jint*) reg_map->location(VMRegImpl::as_VMReg(i)); _callee_registers[i] = src != NULL ? *src : NULL_WORD; #endif if (src == NULL) { set_location_valid(i, false); } else { set_location_valid(i, true); jint* dst = (jint*) register_location(i); *dst = *src; } } } }
void game_update_and_render(RenderQueue* render_queue, Game* game, Input* input, u64 dt) { if (game->entities.entity_count == 0) { V2i pos; pos.x = 7; pos.y = 5; u32 id = spawn_entity(&game->entities); register_location(&game->entities, id, pos, SOUTH); register_appearance(&game->entities, id, 7723); register_controlled(&game->entities, id); } // Handle user input if (input->keys[ESCAPE] != 0) { game->should_end = true; } u32 entity_to_control_mask_include = ENTITY_LOCATED_BIT | ENTITY_CONTROLLED_BIT; u32 entity_to_control_mask_exclude = ENTITY_MOVING_BIT; u32 entity_to_control_count = 0; u32 entity_to_control[MAX_ENTITY_COUNT]; filter_entities(&game->entities, entity_to_control_mask_include, entity_to_control_mask_exclude, entity_to_control, &entity_to_control_count); V2i positions[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entity_to_control_count; i++) { for (u32 j = 0; j < game->entities.located_count; j++) { if (entity_to_control[i] == game->entities.located[j]) { positions[i] = game->entities.positions[j]; break; } } } bool moved = false; Direction direction = NORTH; V2i destination_diff; for (u32 i = 1; i < 5; i++) { i32 key_state = input->keys[i] + game->previous_key_state[i]; if (key_state && entity_to_control_count > 0) { moved = true; destination_diff.x = 0; destination_diff.y = 0; switch (i) { case W: direction = NORTH; destination_diff.y -= 1; break; case A: direction = WEST; destination_diff.x -= 1; break; case S: direction = SOUTH; destination_diff.y += 1; break; case D: direction = EAST; destination_diff.x += 1; break; default: assert(!(bool)"Unreachable!"); break; } } game->previous_key_state[i] = key_state % 2; } if (moved) { for (u32 j = 0; j < entity_to_control_count; j++) { f32 distance = 0.0f; V2i destination; destination.x = positions[j].x + destination_diff.x; destination.y = positions[j].y + destination_diff.y; u32 id = entity_to_control[j]; register_moving(&game->entities, id, destination, distance); update_located_direction(&game->entities, id, direction); } } // Update game->tick += dt; if (game->tick > MS_TO_NS(2000)) { game->tick = 0; for (int y = 0; y < 11; y++) { for (int x = 0; x < 15; x++) { game->tiles[x][y] = rand() % 101925; } } } { // Update moving entities u32 movable_mask = ENTITY_LOCATED_BIT | ENTITY_MOVING_BIT; u32 entities_to_move_count = 0; u32 entities_to_move[MAX_ENTITY_COUNT]; filter_entities(&game->entities, movable_mask, 0, entities_to_move, &entities_to_move_count); u32 not_moving_count = 0; u32 not_moving[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entities_to_move_count; i++) { u32 id = entities_to_move[i]; u32 located_index = 0; for (u32 j = 0; j < game->entities.located_count; j++) { if (game->entities.located[j] == id) { located_index = j; break; } } u32 moving_index = 0; for (u32 j = 0; j < game->entities.moving_count; j++) { if (game->entities.moving[j] == id) { moving_index = j; break; } } if (game->entities.distances[moving_index] >= 1.0f) { game->entities.positions[located_index] = game->entities.destinations[moving_index]; game->entities.distances[moving_index] = 0.0f; not_moving[not_moving_count] = id; not_moving_count += 1; } else { game->entities.distances[moving_index] += 0.1f; } } for (u32 i = 0; i < not_moving_count; i++) { deregister_moving(&game->entities, not_moving[i]); } } // Render render_queue_push_clear(render_queue, 0.0f, 0.0f, 0.0f, 0.0f); game->camera_x = 7.0f; game->camera_y = 5.0f; u32 tile_size = 64; for (u32 r = 0; r < 128; r++) { for (u32 c = 0; c < 128; c++) { f32 x = c - game->camera_x + 7; f32 y = r - game->camera_y + 5; if (0.0f <= x && x < 16.0f && 0 <= y && y < 12.0f) { render_queue_push_sprite(render_queue, game->world[r][c], (i32)(x * tile_size + tile_size), (i32)(y * tile_size + tile_size), tile_size); } } } u32 drawable_mask = ENTITY_LOCATED_BIT | ENTITY_APPEARANCE_BIT; u32 entities_to_draw_count = 0; u32 entities_to_draw[MAX_ENTITY_COUNT]; filter_entities(&game->entities, drawable_mask, 0, entities_to_draw, &entities_to_draw_count); u32 ms[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entities_to_draw_count; i++) { for (u32 j = 0; j < game->entities.entity_count; j++) { if (entities_to_draw[i] == game->entities.ids[j]) { assert((game->entities.masks[j] & drawable_mask) == drawable_mask); ms[i] = game->entities.masks[j]; break; } } } u32 ss[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entities_to_draw_count; i++) { u32 id = entities_to_draw[i]; for (u32 j = 0; j < game->entities.appearance_count; j++) { if (game->entities.appearance[j] == id) { ss[i] = game->entities.sprites[j]; break; } } } f32 xs[MAX_ENTITY_COUNT]; f32 ys[MAX_ENTITY_COUNT]; Direction dirs[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entities_to_draw_count; i++) { u32 id = entities_to_draw[i]; for (u32 j = 0; j < game->entities.located_count; j++) { if (game->entities.located[j] == id) { xs[i] = (f32)game->entities.positions[j].x; ys[i] = (f32)game->entities.positions[j].y; dirs[i] = game->entities.directions[j]; break; } } } f32 dists[MAX_ENTITY_COUNT]; for (u32 i = 0; i < entities_to_draw_count; i++) { for (u32 j = 0; j < game->entities.moving_count; j++) { if (entities_to_draw[i] == game->entities.moving[j]) { dists[i] = game->entities.distances[j]; break; } } } for (u32 i = 0; i < entities_to_draw_count; i++) { u32 sprite_offset = 0; if (ms[i] & ENTITY_MOVING_BIT) { f32 animation_frames = 4.0f; f32 n = (dists[i] / (1.0f / animation_frames)); sprite_offset += (u32)n * 4; switch (dirs[i]) { case NORTH: case SOUTH: sprite_offset += ((u32)ys[i] % 2) * (4 * 4); break; case WEST: case EAST: sprite_offset += ((u32)xs[i] % 2) * (4 * 4); break; } } switch (dirs[i]) { case NORTH: ss[i] = 7721 + sprite_offset; break; case EAST: ss[i] = 7722 + sprite_offset; break; case SOUTH: ss[i] = 7723 + sprite_offset; break; case WEST: ss[i] = 7724 + sprite_offset; break; } } for (u32 i = 0; i < entities_to_draw_count; i++) { if (ms[i] & ENTITY_MOVING_BIT) { V2f v; v.x = xs[i]; v.y = ys[i]; for (u32 j = 0; j < game->entities.moving_count; j++) { if (game->entities.moving[j] == entities_to_draw[i]) { switch (game->entities.directions[j]) { case NORTH: v.y -= game->entities.distances[j]; break; case WEST: v.x -= game->entities.distances[j]; break; case SOUTH: v.y += game->entities.distances[j]; break; case EAST: v.x += game->entities.distances[j]; break; } break; } } xs[i] = v.x - game->camera_x + 7.0f; ys[i] = v.y - game->camera_y + 5.0f; } } for (u32 i = 0; i < entities_to_draw_count; i++) { i32 ts = (i32)tile_size; render_queue_push_sprite(render_queue, ss[i], (i32)(xs[i] * ts + ts), (i32)(ys[i] * ts + ts), ts); } }