void generate_world(World* world, Tile_Info* info, isize ti_count, uint64 seed, Memory_Arena* arena) { Random r_s; Random* r = &r_s; init_random(r, seed); for(isize i = 0; i < world->areas_height; ++i) { for(isize j = 0; j < world->areas_width; ++j) { isize index = i * world->areas_width + j; World_Area* area = world->areas + index; init_world_area(area, arena); area->map.info = info; area->map.info_count = ti_count; generate_tilemap(&area->map, next_random_uint64(r)); for(isize i = 0; i < World_Area_Tilemap_Width; ++i) { Entity* e = world_area_get_next_entity(area); Sim_Body* b = sim_find_body(&area->sim, e->body_id); e->sprite.texture = Get_Texture_Coordinates(0, 96, 32, 64); b->shape.hw = 16; b->shape.hh = 12; b->inv_mass = 1.0f; e->sprite.size = v2(32, 64); e->sprite.center = v2(0, 20); entity_add_event_on_activate(e, test_on_activate); do { b->shape.center = v2( rand_range(r, 0, area->map.w * 32), rand_range(r, 0, area->map.h * 32)); } while (info[tilemap_get_at(&area->map, b->shape.center)].solid); } generate_statics_for_tilemap(&area->sim, &area->map); isize north_link = modulus(i - 1, world->areas_height) * world->areas_width + j; isize south_link = modulus(i + 1, world->areas_height) * world->areas_width + j; isize west_link = i * world->areas_width + modulus(j - 1, world->areas_width); isize east_link = i * world->areas_width + modulus(j + 1, world->areas_width); area->north = Area_Link { v2i(World_Area_Tilemap_Width / 2, World_Area_Tilemap_Height - 1), world->areas + north_link }; area->south = Area_Link { v2i(World_Area_Tilemap_Width / 2, 1), world->areas + south_link }; area->west = Area_Link { v2i(World_Area_Tilemap_Width - 1, World_Area_Tilemap_Height / 2), world->areas + west_link }; area->east = Area_Link { v2i(1, World_Area_Tilemap_Height / 2), world->areas + east_link }; } } }
void VirtualMachine::InitGuiSettings() { m_showSettingsGui = false; const float minVal = 0.0f; const float maxVal = 16.0f; const int width = 200; const int height = 100; const int numVals = 128; m_lineGraphUpdate = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); m_lineGraphMemory = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); }
void Core::InitGuiGraphs() { m_showGraphsGui = false; const float minVal = 0.0f; const float maxVal = 1000.0f / m_fps; const int width = 200; const int height = 100; const int numVals = 128; m_lineGraphRender = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); m_lineGraphUpdate = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); m_lineGraphTotal = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); m_lineGraphGpu = new LineGraph( minVal, maxVal, v2i(width, height), numVals ); }
void animation::update (float dt) { m_time_to_next_frame -= dt; picture_wind *par = (picture_wind *)m_parent; v2i pos = (in.mouse.pos - v2i (10,10) - par->m_pos) / par->m_scale; Rect <int> r (v2i (240, 70), v2i (11, 11)); if (r << in.mouse.pos && in.mouse.mbutton [MOUSE_LEFT].just_pressed) { m_prev_layer_half_transparent = par->m_layers.back (); FOR_ARRAY_2D (v, m_prev_layer_half_transparent) { m_prev_layer_half_transparent[v].a /= 2; } par->m_layers.push_back (rgba_array (true)); par->m_layers.back ().init (D_W, D_H); par->m_layers.back ().clear (CLR (0,0,0,0)); par->m_cur_layer = par->m_layers.size () - 1; }
void Core::GuiGraphs() { const v2i pos = v2i(300, Window::Get()->Sizei().y - 20 ); Imgui::Begin("Main Analytics", pos ); Imgui::Print("Total"); Imgui::LineGraph(m_lineGraphTotal); Imgui::Print("Update"); Imgui::LineGraph(m_lineGraphUpdate); Imgui::Print("Render"); Imgui::LineGraph(m_lineGraphRender); Imgui::Print("GPU"); Imgui::LineGraph(m_lineGraphGpu); Imgui::End(); }
void load_assets() { isize w, h; renderer->texture = ogl_load_texture("data/graphics.png", &w, &h); renderer->texture_width = w; renderer->texture_height = h; game->body_font = load_spritefont("data/gohufont-14.glyphs", v2i(2048 - 1142, 0)); body_font = game->body_font; game->state = Game_State_Play; play_state_init(); play_state_start(); #if DEBUG //load_test_assets(); //game->state = Game_State_None; #endif }
void Core::GuiStats() { const int padding = 5; const v2i windowDimen = Window::Get()->Sizei(); const float deltaMs = 1000.0f / m_fps; Imgui::Begin("Analytics", v2i(padding, windowDimen.y-padding) ); Imgui::Minimize(); Imgui::FillBarFloat("Total", m_msUpdate+m_msRender, 0.0f, deltaMs ); Imgui::FillBarFloat("Update", m_msUpdate, 0.0f, deltaMs ); Imgui::FillBarFloat("Render", m_msRender, 0.0f, deltaMs ); Imgui::FillBarFloat("GPU", m_msGpu, 0.0f, deltaMs ); Imgui::CheckBox("Show Graphs", m_showGraphsGui ); VirtualMachine::Get()->GuiStats(); SoundMngr::Get()->GuiStats(); Imgui::End(); if ( m_showGraphsGui ) { UpdateGuiGraphs(); GuiGraphs(); } }
void VirtualMachine::GuiSettings() { m_lineGraphUpdate->PushVal( m_updateMs ); m_lineGraphUpdate->SetMaxVal(m_dt*1000.0f); m_lineGraphMemory->SetMaxVal( (float)m_vm->GetDesiredByteMemoryUsageHard() ); m_lineGraphMemory->PushVal( (float)m_vm->GetCurrentMemoryUsage() ); int workPerIncrement = m_vm->GetGC()->GetWorkPerIncrement(); int destructPerIncrement = m_vm->GetGC()->GetDestructPerIncrement(); int memUsageSoft = m_vm->GetDesiredByteMemoryUsageSoft(); int memUsageHard = m_vm->GetDesiredByteMemoryUsageHard(); const v2i pos = v2i(300, Window::Get()->Sizei().y - 20 ); Imgui::Begin("GameMonkey Settings", pos); Imgui::Print("Update"); Imgui::LineGraph( m_lineGraphUpdate ); Imgui::Print("Memory"); Imgui::LineGraph( m_lineGraphMemory ); Imgui::FillBarInt("Mem Usage (Bytes)", m_vm->GetCurrentMemoryUsage(), 0, m_vm->GetDesiredByteMemoryUsageHard() ); Imgui::Header("Garbage Collector"); Imgui::SliderInt( "Work Per Increment", workPerIncrement, 1, 600 ); Imgui::SliderInt( "Destructs Per Increment", destructPerIncrement, 1, 600 ); Imgui::SliderInt( "Mem Usage Soft", memUsageSoft, 200000, memUsageHard ); Imgui::SliderInt( "Mem Usage Hard", memUsageHard, memUsageSoft+500, memUsageSoft+200000 ); Imgui::Separator(); Imgui::FillBarInt("GC Warnings", m_vm->GetStatsGCNumWarnings(), 0, 200 ); Imgui::FillBarInt("GC Full Collects", m_vm->GetStatsGCNumFullCollects(), 0, 200 ); Imgui::FillBarInt("GC Inc Collects", m_vm->GetStatsGCNumIncCollects(), 0, 200 ); Imgui::End(); m_vm->SetDesiredByteMemoryUsageSoft(memUsageSoft); m_vm->SetDesiredByteMemoryUsageHard(memUsageHard); m_vm->GetGC()->SetWorkPerIncrement(workPerIncrement); m_vm->GetGC()->SetDestructPerIncrement(destructPerIncrement); }
v2i Font::CalcDimen( const char* a_text ) const { return v2i(CalcWidth(a_text), CalcHeight() ); }
void VirtualMachine::GuiThreadAllocations() { const v2i pos = v2i(300, Window::Get()->Sizei().y - 20 ); Imgui::Begin("Thread Allocations (Live)", pos); m_freezeThreadAllocationsGui = Imgui::CheckBox("Freeze", m_freezeThreadAllocationsGui); if (!m_freezeThreadAllocationsGui) { std::map<const gmFunctionObject*, ThreadAllocationItem>::iterator i = m_threadAllocationsHistory.begin(); while (i != m_threadAllocationsHistory.end()) { i->second.eraseCountdown -= 1; if (i->second.eraseCountdown <= 0) { i = m_threadAllocationsHistory.erase(i); } else { ++i; } } } if (!m_freezeThreadAllocationsGui) { std::map<const gmFunctionObject*, int>::const_iterator a = m_vm->GetAllocCountIteratorBegin(); std::map<const gmFunctionObject*, int>::const_iterator b = m_vm->GetAllocCountIteratorEnd(); for (; a != b; ++a) { ThreadAllocationItem& item = m_threadAllocationsHistory[a->first]; item.allocations = a->second; item.eraseCountdown = 300; } } { std::map<const gmFunctionObject*, ThreadAllocationItem>::const_iterator a = m_threadAllocationsHistory.begin(); std::map<const gmFunctionObject*, ThreadAllocationItem>::const_iterator b = m_threadAllocationsHistory.end(); for (; a != b; ++a) { const gmFunctionObject* func = a->first; const gmuint32 sourceid = func->GetSourceId(); const char* sourcecode = NULL; const char* filename = NULL; m_vm->GetSourceCode(sourceid, sourcecode, filename); int allocations = a->second.allocations; if (allocations <= 0) continue; char buffer[128] = { '.' }; const char* fname = func->GetDebugName(); const char* status = a->second.eraseCountdown == 300 ? "new" : "old"; sprintf(buffer, "%s:%s [%s]", filename, fname, status); int len = strlen(buffer); memset( &buffer[len], '.', sizeof(buffer)-len-1); itoa(allocations, buffer+50, 10); Imgui::Print(buffer); } } Imgui::End(); }
void Input::SetMousePos( int x, int y ) { SDL_WarpMouse( x, Window::Get()->Sizei().y - y ); m_mousePos = v2i(x,y); }
int main(int argc, char** argv) { //stbi_set_flip_vertically_on_load(1); if(SDL_Init(SDL_INIT_EVERYTHING) != 0) { Log_Error("Could not init SDL"); Log_Error(SDL_GetError()); return 1; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1); SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); int32 window_display_index = 0; #if 1 window_display_index = 1; #endif SDL_Window* window = SDL_CreateWindow("Rituals", SDL_WINDOWPOS_CENTERED_DISPLAY(window_display_index), SDL_WINDOWPOS_CENTERED_DISPLAY(window_display_index), 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS); if(window == NULL) { Log_Error("Could not create window"); Log_Error(SDL_GetError()); return 1; } printf("%s \n", SDL_GetError()); SDL_GLContext glctx = SDL_GL_CreateContext(window); if(ogl_LoadFunctions() == ogl_LOAD_FAILED) { Log_Error("Could not load OpenGL 3.3 functions..."); return 1; } int ret = SDL_GL_SetSwapInterval(-1); { #define _check_gl_attribute(attr, val) int _##attr##_val; \ int _##attr##_success = SDL_GL_GetAttribute(attr, &_##attr##_val); \ gl_checks[gl_check_count++] = _##attr##_val == val; \ gl_names[gl_check_count - 1] = #attr; \ gl_vals[gl_check_count - 1] = _##attr##_val; \ gl_exp_vals[gl_check_count - 1] = val; //check if we got everything bool gl_checks[64]; char* gl_names[64]; int gl_vals[64]; int gl_exp_vals[64]; isize gl_check_count = 0; _check_gl_attribute(SDL_GL_RED_SIZE, 8); _check_gl_attribute(SDL_GL_GREEN_SIZE, 8); _check_gl_attribute(SDL_GL_BLUE_SIZE, 8); _check_gl_attribute(SDL_GL_ALPHA_SIZE, 8); _check_gl_attribute(SDL_GL_DOUBLEBUFFER, 1); _check_gl_attribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); _check_gl_attribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); _check_gl_attribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1); _check_gl_attribute(SDL_GL_ACCELERATED_VISUAL, 1); _check_gl_attribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); for(isize i = 0; i < gl_check_count; ++i) { printf("%s %s: wanted %d, got %d \n", gl_names[i], gl_checks[i] ? "succeeeded" : "failed", gl_exp_vals[i], gl_vals[i]); } } // Game initializiation game = Allocate(Game, 1); { game->window = window; game->state = Game_State_None; game->meta_arena = Allocate(Memory_Arena, 1); init_memory_arena(game->meta_arena, isz(Memory_Arena) * 10); game->game_arena = new_memory_arena(Kilobytes(64), game->meta_arena); game->asset_arena = new_memory_arena(Megabytes(512), game->meta_arena); game->temp_arena = new_memory_arena(Megabytes(64), game->meta_arena); game->play_arena = new_memory_arena(Megabytes(512), game->meta_arena); game->renderer_arena = new_memory_arena(Megabytes(32), game->meta_arena); game->base_path = SDL_GetBasePath(); game->base_path_length = strlen(game->base_path); game->input = Arena_Push_Struct(game->game_arena, Game_Input); game->input->scancodes = Arena_Push_Array(game->game_arena, int8, SDL_NUM_SCANCODES); game->input->keycodes = Arena_Push_Array(game->game_arena, int8, SDL_NUM_SCANCODES); game->input->mouse = Arena_Push_Array(game->game_arena, int8, 16); init_random(&game->r, time(NULL)); //TODO(will) load window settings from file game->window_size = v2i(1280, 720); game->scale = 1.0f; game->renderer = Arena_Push_Struct(game->game_arena, Renderer); renderer_init(game->renderer, game->renderer_arena); renderer = game->renderer; input = game->input; } load_assets(); bool running = true; SDL_Event event; glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //glClearColor(1, 1, 1, 1); play_state->current_time = SDL_GetTicks(); play_state->prev_time = play_state->current_time; while(running) { uint64 start_ticks = SDL_GetTicks(); if(game->input->num_keys_down < 0) game->input->num_keys_down = 0; if(game->input->num_mouse_down < 0) game->input->num_mouse_down = 0; if(game->input->num_keys_down > 0) for(int64 i = 0; i < SDL_NUM_SCANCODES; ++i) { int8* t = game->input->scancodes + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } t = game->input->keycodes + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } } if(game->input->num_mouse_down > 0) for(int64 i = 0; i < 16; ++i) { int8* t = game->input->mouse + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } } while(SDL_PollEvent(&event)) { //TODO(will) handle text input switch(event.type) { case SDL_QUIT: running = false; break; case SDL_WINDOWEVENT: update_screen(); break; case SDL_KEYDOWN: game->input->num_keys_down++; if(!event.key.repeat) { game->input->scancodes[event.key.keysym.scancode] = State_Just_Pressed; if(event.key.keysym.sym < SDL_NUM_SCANCODES) { game->input->keycodes[event.key.keysym.sym] = State_Just_Pressed; } } break; case SDL_KEYUP: game->input->num_keys_down--; if(!event.key.repeat) { game->input->scancodes[event.key.keysym.scancode] = State_Just_Released; if(event.key.keysym.sym < SDL_NUM_SCANCODES) { game->input->keycodes[event.key.keysym.sym] = State_Just_Released; } } break; case SDL_MOUSEBUTTONDOWN: game->input->num_mouse_down++; game->input->mouse[event.button.button] = State_Just_Pressed; break; case SDL_MOUSEBUTTONUP: game->input->num_mouse_down--; game->input->mouse[event.button.button] = State_Just_Released; break; } } int mx, my; SDL_GetMouseState(&mx, &my); input->mouse_x = mx; input->mouse_y = my; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); update(); SDL_GL_SwapWindow(window); uint64 frame_ticks = SDL_GetTicks() - start_ticks; //if(frame_ticks > 18) printf("Slow frame! %d\n", frame_ticks); } SDL_Quit(); return 0; }
void TileViewer_Update(t_app_tile_viewer *app) { ALLEGRO_BITMAP *bmp = app->box->gfx_buffer; // Skip update if not active if (!app->active) return; // If skin has changed, redraw everything if (app->box->flags & GUI_BOX_FLAGS_DIRTY_REDRAW_ALL_LAYOUT) { TileViewer_Layout(app, FALSE); app->box->flags &= ~GUI_BOX_FLAGS_DIRTY_REDRAW_ALL_LAYOUT; app->dirty = TRUE; } bool dirty_all = app->dirty || Palette_EmulationDirtyAny; bool dirty = dirty_all; // Update hovered tile index { const int mx = app->tiles_display_zone->mouse_x; const int my = app->tiles_display_zone->mouse_y; // Msg(MSGT_USER, "mx = %d, my = %d", mx, my); if (app->tiles_display_zone->mouse_action & WIDGET_MOUSE_ACTION_HOVER) app->tile_hovered = ((my / 8) * 16) + mx / 8; else app->tile_hovered = -1; } // Compute the tile that is to display in the bottom info line int tile_current = (app->tile_hovered != -1) ? app->tile_hovered : app->tile_selected; bool tile_current_refresh = /*(tile_current == -1) ? FALSE : */ (((tile_current != app->tile_displayed) || dirty_all || tgfx.Tile_Dirty [tile_current])); int tile_current_addr = -1; const v2i tiles_frame_pos = app->tiles_display_frame.pos; const v2i tile_selected_pos = v2i(app->tile_selected_frame.pos.x + 2, app->tile_selected_frame.pos.y + 2); int vram_addr_min = 0x0000; int vram_addr_size = 0; int vram_tile_size = 1; // Then redraw all tiles ALLEGRO_LOCKED_REGION* locked_region = al_lock_bitmap(app->box->gfx_buffer, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); switch (g_driver->vdp) { case VDP_SMSGG: { widget_set_enabled(app->vram_addr_tms9918_scrollbar, false); vram_addr_min = 0; vram_addr_size = 0x4000; vram_tile_size = 32; int n = 0; const u8 * nd = &tgfx.Tile_Decoded[0][0]; const u32 * palette_host = app->palette ? &Palette_EmulationToHostGui[16] : &Palette_EmulationToHostGui[0]; for (int y = 0; y != app->tiles_height; y++) { for (int x = 0; x != app->tiles_width; x++) { if (tgfx.Tile_Dirty [n] & TILE_DIRTY_DECODE) Decode_Tile (n); if (dirty_all || tgfx.Tile_Dirty [n]) { VDP_Mode4_DrawTile(app->box->gfx_buffer, locked_region, nd, palette_host, tiles_frame_pos.x+(x * 8), tiles_frame_pos.y+(y * 8), 0); tgfx.Tile_Dirty [n] = 0; dirty = TRUE; } if (n == tile_current) { tile_current_addr = vram_addr_min + (n * 32); VDP_Mode4_DrawTile(app->box->gfx_buffer, locked_region, nd, palette_host, tile_selected_pos.x, tile_selected_pos.y, 0); } n ++; nd += 64; } } break; } case VDP_TMS9918: { widget_set_enabled(app->vram_addr_tms9918_scrollbar, true); vram_addr_min = 0x0000 + app->vram_addr_tms9918_current*0x1000; vram_addr_size = 0x1000; vram_tile_size = 8; const int fg_color = Palette_EmulationToHostGui[app->palette + 1]; const int bg_color = Palette_EmulationToHostGui[(app->palette != 0) ? 1 : 15]; const u8 * addr = VRAM + vram_addr_min; //VRAM = g_machine.VDP.sg_pattern_gen_address; // addr = &VRAM[apps.opt.Tiles_Base]; int n = 0; for (int y = 0; y != app->tiles_height; y ++) { for (int x = 0; x != app->tiles_width; x ++) { if ((addr - VRAM) > 0x4000) break; VDP_Mode0123_DrawTile(bmp, locked_region, tiles_frame_pos.x+(x * 8), tiles_frame_pos.y+(y * 8), addr, fg_color, bg_color); if (n == tile_current) { tile_current_addr = vram_addr_min + (n * 8); VDP_Mode0123_DrawTile(bmp, locked_region, tile_selected_pos.x, tile_selected_pos.y, addr, fg_color, bg_color); } n++; addr += 8; } } dirty = TRUE; // to be replaced later break; } } al_unlock_bitmap(app->box->gfx_buffer); // Refresh top status line (address range) al_set_target_bitmap(bmp); { // FIXME-OPT const int y = -1; al_draw_filled_rectangle(0, y + 1, app->vram_addr_tms9918_scrollbar->enabled ? app->vram_addr_tms9918_scrollbar->frame.pos.x-1 : 128-1, y + 11+1, COLOR_SKIN_WINDOW_BACKGROUND); char buf[64]; sprintf(buf, "Range: $%04X-$%04X", vram_addr_min, vram_addr_min+vram_addr_size-1); Font_Print(FONTID_SMALL, buf, 0, y + 1, COLOR_SKIN_WINDOW_TEXT); dirty = true; } // Refresh bottom status line (selected tile) if (dirty_all || tile_current_refresh) { const int y = app->tiles_display_frame.GetMax().y; al_draw_filled_rectangle(16, y + 1, 127+1, y + 11+1, COLOR_SKIN_WINDOW_BACKGROUND); dirty = TRUE; if (tile_current != -1) { // Description char addr[16]; if (tile_current_addr != -1) sprintf(addr, "$%04X", tile_current_addr); else sprintf(addr, "????"); char buf[128]; const int tile_index = tile_current_addr / vram_tile_size; sprintf(buf, Msg_Get(MSG_TilesViewer_Tile), tile_index, tile_index, addr); Font_Print(FONTID_SMALL, buf, 16, y + 1, COLOR_SKIN_WINDOW_TEXT); app->tile_displayed = tile_current; } else { // Fill tile with black const t_frame* fr = &app->tile_selected_frame; al_draw_filled_rectangle(fr->pos.x+2, fr->pos.y+2, fr->pos.x+2+8, fr->pos.y+2+8, COLOR_BLACK); } } if (dirty_all || dirty) app->dirty = FALSE; }