/* * 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 "candy_gear.h" #include "color.h" #include "core.h" #include "font.h" #include "graphic.h" #include "key.h" #include "log.h" #include "palette.h" #include "point.h" #include "rect.h" #include "sound.h" #include "sprite.h" #include "texture.h" cg_sCore cg_core; void handle_error(mrb_state *mrb) { mrb_print_error(mrb); cg_core.quit_game = SDL_TRUE; } int main(int argc, char *argv[]) { SDL_Event event; Uint32 frame_start; mrb_state *mrb = mrb_open(); mrb_value main_obj; mrb_sym sym_init, sym_key_down, sym_key_up, sym_quit, sym_tick; FILE *fp; LoaderStack core_loader; cg_core.config_file = argv[1]; cg_Core_init(&core_loader); if(!cg_Core_load(&core_loader)) return 1; if (!mrb) { /* handle error */ } mrb_define_module(mrb, "CandyGear"); cg_candy_gear_init(mrb); cg_color_init(mrb); cg_font_init(mrb); cg_graphic_init(mrb); cg_key_init(mrb); cg_log_init(mrb); cg_palette_init(mrb); cg_point_init(mrb); cg_rect_init(mrb); cg_sound_init(mrb); cg_sprite_init(mrb); cg_texture_init(mrb); main_obj = mrb_obj_iv_inspect(mrb, mrb->top_self); sym_init = mrb_intern_cstr(mrb, "init"); sym_key_down = mrb_intern_cstr(mrb, "key_down"); sym_key_up = mrb_intern_cstr(mrb, "key_up"); sym_quit = mrb_intern_cstr(mrb, "quit"); sym_tick = mrb_intern_cstr(mrb, "tick"); fp = fopen(argv[2], "r"); mrb_load_irep_file(mrb, fp); fclose(fp); if (mrb->exc) handle_error(mrb); mrb_funcall_id(mrb, main_obj, sym_init, 0); if (mrb->exc) handle_error(mrb); frame_start = SDL_GetTicks(); // Game main loop. while(!cg_core.quit_game) { // Get input. while(SDL_PollEvent(&event) != 0) { switch(event.type) { case SDL_KEYDOWN: mrb_funcall_id( mrb, main_obj, sym_key_down, 1, mrb_int_value(mrb, event.key.keysym.sym)); break; case SDL_KEYUP: mrb_funcall_id( mrb, main_obj, sym_key_up, 1, mrb_int_value(mrb, event.key.keysym.sym)); break; case SDL_MOUSEMOTION: break; case SDL_MOUSEBUTTONDOWN: break; case SDL_MOUSEBUTTONUP: break; case SDL_QUIT: mrb_funcall_id(mrb, main_obj, sym_quit, 0); break; } } // Clear buffer. SDL_SetRenderDrawColor(cg_core.renderer, 0x00, 0x00, 0x00, 0xff); SDL_RenderClear(cg_core.renderer); mrb_funcall_id(mrb, main_obj, sym_tick, 0); if (mrb->exc) handle_error(mrb); // Copy buffer to the screen and display it. SDL_SetRenderTarget(cg_core.renderer, NULL); SDL_RenderCopy( cg_core.renderer, cg_core.pre_screen_buffer, NULL, &cg_core.screen_rect); SDL_RenderPresent(cg_core.renderer); SDL_SetRenderTarget(cg_core.renderer, cg_core.pre_screen_buffer); // Timer { Uint32 frame_stop, frame_duration; frame_stop = SDL_GetTicks(); frame_duration = frame_stop - frame_start; // If frame take less time than maximum allowed. if(cg_core.max_frame_duration_ms > frame_duration) SDL_Delay(cg_core.max_frame_duration_ms - frame_duration); frame_start = frame_stop; } } mrb_close(mrb); cg_Core_unload(&core_loader); return 0; }