/* * Copyright 2022 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "candy_gear.hpp" #include "core.hpp" #include "key.hpp" #include "model.hpp" #include "rotation_3d.hpp" #include "sound.hpp" #include "sprite.hpp" #include "texture.hpp" #include "vector_3d.hpp" cg_sCore cg_core; static void handle_error(mrb_state *mrb) { mrb_print_error(mrb); cg_core.quit_game = true; } int main(int argc, char *argv[]) { using namespace std::chrono; using namespace std::this_thread; SDL_Event event; // Random numbers random_number_generator.seed(random_seed()); mrb_value main_obj; mrb_sym sym_init, sym_key_down, sym_key_up, sym_quit, sym_tick; FILE *fp; cg_core.config_file = argv[1]; try{ cg_sCore::loader.execute(nullptr); } catch(const CommandError &error) { cg_core.log.message(Log::Level::Fatal, error.what()); return 1; } mrb_define_module(cg_core.mrb, "CandyGear"); cg_candy_gear_init(cg_core.mrb); cg_key_init(cg_core.mrb); cg_model_init(cg_core.mrb); cg_rotation_3d_init(cg_core.mrb); cg_sound_init(cg_core.mrb); cg_sprite_init(cg_core.mrb); cg_texture_init(cg_core.mrb); cg_vector_3d_init(cg_core.mrb); main_obj = mrb_obj_iv_inspect(cg_core.mrb, cg_core.mrb->top_self); sym_init = mrb_intern_cstr(cg_core.mrb, "init"); sym_key_down = mrb_intern_cstr(cg_core.mrb, "key_down"); sym_key_up = mrb_intern_cstr(cg_core.mrb, "key_up"); sym_quit = mrb_intern_cstr(cg_core.mrb, "quit"); sym_tick = mrb_intern_cstr(cg_core.mrb, "tick"); fp = fopen(argv[2], "r"); mrb_load_irep_file(cg_core.mrb, fp); fclose(fp); if (cg_core.mrb->exc) handle_error(cg_core.mrb); else { mrb_funcall_id(cg_core.mrb, main_obj, sym_init, 0); if (cg_core.mrb->exc) handle_error(cg_core.mrb); } auto frame_start = steady_clock::now(); // Game main loop. while(!cg_core.quit_game) { // Get input. while(SDL_PollEvent(&event) != 0) { switch(event.type) { case SDL_KEYDOWN: mrb_funcall_id( cg_core.mrb, main_obj, sym_key_down, 1, mrb_int_value(cg_core.mrb, event.key.keysym.sym)); break; case SDL_KEYUP: mrb_funcall_id( cg_core.mrb, main_obj, sym_key_up, 1, mrb_int_value(cg_core.mrb, event.key.keysym.sym)); break; case SDL_MOUSEMOTION: break; case SDL_MOUSEBUTTONDOWN: break; case SDL_MOUSEBUTTONUP: break; case SDL_QUIT: mrb_funcall_id(cg_core.mrb, main_obj, sym_quit, 0); break; } } mrb_funcall_id(cg_core.mrb, main_obj, sym_tick, 0); if (cg_core.mrb->exc) handle_error(cg_core.mrb); cg_core.vk_renderer->draw(); // Timer { auto frame_stop = steady_clock::now(); auto frame_duration = frame_stop - frame_start; // If frame take less time than maximum allowed. if(cg_core.max_frame_duration > frame_duration) sleep_for(cg_core.max_frame_duration - frame_duration); frame_start = frame_stop; } } cg_sCore::loader.revert(nullptr); return 0; }