From 1b0c8fb53a4f3335dc9132e4beabe6602f682ea5 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sat, 14 Sep 2019 19:51:37 +0200 Subject: Use autotools instead of hand-written Makefile --- src/main.c | 456 ------------------------------------------------------------- 1 file changed, 456 deletions(-) delete mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 94db4e5..0000000 --- a/src/main.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement - * Copyright (C) 2019 Ludovic Pouzenc - * - * This file is part of demoscene-eo. - * - * demoscene-eo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * demoscene-eo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with demoscene-eo. If not, see - */ -#include "main.h" -#include "scene00.h" -#include "scene01.h" -#include "scene02.h" - -#include // calloc() -#include // bzero() -#include // mmap() -#include // sem_t, sem_init(), Link with -pthread -#include // fork() -#include // wait() -#include // errno -#include // uint32_t -#include // printf() -#include // sigaction() - -#ifdef DEBUG_SEM -#define TRACE_SEM(sem,op,hint) printf("%s(): %s(%s) %s\n", __func__, op, #sem, hint) -#else -#define TRACE_SEM(sem,op,hint) -#endif - -#define SCENE_COUNT 3 -#define SCENE_NEXT do { shm->scene = (shm->scene+1)%SCENE_COUNT; } while(0) - -#define SEM_POST(sem,errcode) \ - do { \ - TRACE_SEM(sem,"sem_post",""); \ - if (sem_post(sem) == -1) { return errcode; } \ - } while(0) - -#define SEM_WAIT(sem,errcode) \ - do { \ - TRACE_SEM(sem,"sem_wait","call"); \ - while (sem_wait(sem) == -1) { \ - switch(errno) { \ - case EINTR: \ - case EAGAIN: \ - break; \ - default: \ - return errcode; \ - } \ - } \ - TRACE_SEM(sem,"sem_wait","done"); \ - } while(0) - -typedef struct { - sem_t worker_gl_can_render, worker_sdl_can_render, parent_can_read_result; - int scene, paused, done; - graphical_env_t ge; - scene00_env_t s00e; - scene01_env_t s01e; - scene02_env_t s02e; -} shm_t; - -int do_fork1(); -int do_fork2(); -int parent(); -int worker_sdl(); -int worker_gl(); - -static int skip = 0; -shm_t *shm; - -int main() { - TRACE("call"); - shm = mmap(NULL, sizeof(shm_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0); - if (shm == NULL) return 1; - bzero(shm, sizeof(shm_t)); - - if (sem_init(&shm->worker_gl_can_render, 1, 0) < 0) return 2; - if (sem_init(&shm->worker_sdl_can_render, 1, 0) < 0) return 3; - if (sem_init(&shm->parent_can_read_result, 1, 0) < 0) return 4; - - return do_fork1(); -} - -int do_fork1() { - TRACE("call"); - fflush(stdout); - switch (fork()) { - case -1: return 4; break; - case 0: return worker_sdl(); break; - default: return do_fork2(); break; - } -} - -int do_fork2() { - TRACE("call"); - fflush(stdout); - switch (fork()) { - case -1: return 5; break; - case 0: return worker_gl(); break; - default: return parent(); break; - } -} - -int parent() { - int lastscene=-1, res, child_status; - caca_event_t caca_ev; - - TRACE("call"); - - // Initialize libcaca (http://caca.zoy.org/doxygen/libcaca/caca_8h.html) - shm->ge.dp = caca_create_display(NULL); - if(!shm->ge.dp) return 1; - caca_set_display_title(shm->ge.dp, "demoscene-eo"); - caca_set_display_time(shm->ge.dp, 41666); // 1e6µs/24 = 41666.66... It is ~24 fps - shm->ge.cv = caca_get_canvas(shm->ge.dp); - - shm->ge.d = caca_create_dither(32, FBUF_W, FBUF_H, FBUF_W*4, 0x00ff0000, 0x0000ff00, 0x000000ff, 0); - if (!shm->ge.d) return 2; - caca_set_dither_color(shm->ge.d, "16"); - - // Main libcaca loop for caca window - shm->ge.framecount=0; - do { - - // Check canvas size at every frame because of unreliable CACA_EVENT_RESIZE - shm->ge.w = caca_get_canvas_width(shm->ge.cv); - shm->ge.h = caca_get_canvas_height(shm->ge.cv); - if ( EXPR_MIN_SIZE ) { - caca_set_color_ansi(shm->ge.cv, CACA_BLACK, CACA_WHITE); - caca_put_str(shm->ge.cv, 0, 0, "Need a minimum of " TEXT_MIN_SIZE " terminal"); - } else if (!shm->paused) { - // init / free if scene transition - if (lastscene != shm->scene) { - switch(lastscene) { - case 0: scene00_free_caca(&shm->ge, &shm->s00e); break; - case 1: scene01_free_caca(&shm->ge, &shm->s01e); break; - case 2: scene02_free_caca(&shm->ge, &shm->s02e); break; - } - } - while (lastscene != shm->scene) { - shm->ge.sdl_ticks = SDL_GetTicks(); - shm->ge.sc_framecount = 0; - switch(shm->scene) { - case 0: res = scene00_init_caca(&shm->ge, &shm->s00e); break; - case 1: res = scene01_init_caca(&shm->ge, &shm->s01e); break; - case 2: res = scene02_init_caca(&shm->ge, &shm->s02e); break; - } - // If scene init fail, skip to the next one - if (res) SCENE_NEXT; else lastscene = shm->scene; - } - shm->ge.sdl_ticks = SDL_GetTicks(); // This value wraps if the program runs for more than ~49 days - - SEM_POST(&shm->worker_gl_can_render,30); - SEM_WAIT(&shm->parent_can_read_result,31); - - SEM_POST(&shm->worker_sdl_can_render,32); - SEM_WAIT(&shm->parent_can_read_result,33); - - // Compute current scene frame (caca part) - switch(shm->scene) { - case 0: res = scene00_next_caca(&shm->ge, &shm->s00e); break; - case 1: res = scene01_next_caca(&shm->ge, &shm->s01e); break; - case 2: res = scene02_next_caca(&shm->ge, &shm->s02e); break; - } - if (res) SCENE_NEXT; - shm->ge.framecount++; - shm->ge.sc_framecount++; - } - // Display it - caca_refresh_display(shm->ge.dp); // Auto framerate limiting (see caca_set_display_time()) - - // Event handling for the libcaca "window" (depending on CACA_DRIVER env variable) - if (caca_get_event(shm->ge.dp, CACA_EVENT_KEY_PRESS|CACA_EVENT_RESIZE|CACA_EVENT_QUIT, &caca_ev, 0)) { - switch(caca_get_event_type(&caca_ev)) { - case CACA_EVENT_QUIT: - shm->done = 1; - break; - case CACA_EVENT_KEY_PRESS: - switch(caca_get_event_key_ch(&caca_ev)) { - case 'q': shm->done = 1; break; - case 'p': shm->paused = !shm->paused; break; - case CACA_KEY_ESCAPE: SCENE_NEXT; break; - } - break; - /* On Debian 10, no CACA_EVENT_RESIZE fired when using x11 CACA_DRIVER - case CACA_EVENT_RESIZE: - w = caca_get_event_resize_width(&caca_ev); - h = caca_get_event_resize_height(&caca_ev); - small = EXPR_MIN_SIZE; - break; - */ - default: - break; - } - } - } while(!shm->done); - - caca_free_dither(shm->ge.d); - caca_free_display(shm->ge.dp); - shm->ge.cv=NULL; - - // reap forked processes (order doesn't matter) - if (wait(&child_status) != -1) { - if (child_status > 0) return child_status; - } - if (wait(&child_status) != -1) { - if (child_status > 0) return child_status; - } - return 0; -} - -static void worker_sdl_sighandler(int sig) { - TRACE("call"); - if ( sig == SIGALRM ) { - skip = 1; - sem_post(&shm->worker_sdl_can_render); - } -} - -int worker_sdl() { - int lastscene=-1, res; - struct sigaction sa; -#ifdef DEBUG - Uint32 sdl_win_flags = 0; //XXX for final version, consider adding SDL_WINDOW_HIDDEN - SDL_Event sdl_ev; -#else - Uint32 sdl_win_flags = SDL_WINDOW_HIDDEN; -#endif - SDL_RendererInfo renderer_info; - - TRACE("call"); - - sa.sa_handler = worker_sdl_sighandler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGALRM, &sa, NULL) == -1) return 2; - - // Initialize SDL (http://wiki.libsdl.org/SDL_CreateWindowAndRenderer) - // Useful snippet : https://gist.github.com/koute/7391344 - res = SDL_Init(SDL_INIT_VIDEO); - if (res == -1) return 3; - atexit(SDL_Quit); - - res = SDL_CreateWindowAndRenderer(FBUF_W, FBUF_H, sdl_win_flags, &shm->ge.sdl_win, &shm->ge.sdl_rndr); - if (res == -1) return 4; - SDL_SetWindowTitle(shm->ge.sdl_win, "SDL debug"); - res = SDL_GetRendererInfo(shm->ge.sdl_rndr, &renderer_info); - if (res < 0) return 5; - if (!(renderer_info.flags & SDL_RENDERER_ACCELERATED)) return 6; - if (!(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE)) return 7; - shm->ge.sdl_target = SDL_CreateTexture(shm->ge.sdl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FBUF_W, FBUF_H); - if (shm->ge.sdl_target == NULL) return 9; - - - while (!shm->done) { - alarm(1); - SEM_WAIT(&shm->worker_sdl_can_render,20); - alarm(0); - - if (!shm->paused && !skip) { - // init / free if scene transition - if (lastscene != shm->scene) { - switch(lastscene) { - case 0: scene00_free_sdl(&shm->ge, &shm->s00e); break; - case 1: scene01_free_sdl(&shm->ge, &shm->s01e); break; - case 2: scene02_free_sdl(&shm->ge, &shm->s02e); break; - } - } - while (lastscene != shm->scene ) { - shm->ge.sdl_ticks = SDL_GetTicks(); - shm->ge.sc_framecount = 0; - switch(shm->scene) { - case 0: res = scene00_init_sdl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_init_sdl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_init_sdl(&shm->ge, &shm->s02e); break; - } - // If scene init fail, skip to the next one - if (res) SCENE_NEXT; else lastscene = shm->scene; - } - // Compute current scene frame (sdl part) - switch(shm->scene) { - case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_next_sdl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break; - } - if (res) SCENE_NEXT; - } - if (skip) skip = 0; - -#ifdef DEBUG - // Event handling for the SDL window (debug purposes) - while(SDL_PollEvent(&sdl_ev)) { - switch(sdl_ev.type) { - case SDL_QUIT: - shm->done = 1; - break; - case SDL_KEYDOWN: - switch(sdl_ev.key.keysym.sym) { - case SDLK_q: shm->done = 1; break; - case SDLK_p: shm->paused = !shm->paused; break; - case SDLK_ESCAPE: SCENE_NEXT; break; - } - break; - default: - break; - } - } -#endif - SEM_POST(&shm->parent_can_read_result, 21); - } - - SDL_DestroyRenderer(shm->ge.sdl_rndr); - SDL_DestroyTexture(shm->ge.sdl_target); - SDL_DestroyWindow(shm->ge.sdl_win); - - return 0; -} - -static void worker_gl_sighandler(int sig) { - TRACE("call"); - if ( sig == SIGALRM ) { - skip = 1; - sem_post(&shm->worker_gl_can_render); - } -} - -int worker_gl() { - int lastscene=-1, res; - struct sigaction sa; -#ifdef DEBUG - Uint32 sdl_win_flags = SDL_WINDOW_OPENGL; - SDL_Event gl_ev; -#else - Uint32 sdl_win_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN; -#endif - SDL_RendererInfo renderer_info; - - TRACE("call"); - - sa.sa_handler = worker_gl_sighandler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGALRM, &sa, NULL) == -1) return 2; - - // Initialize SDL for GL. Useful snippet : https://gist.github.com/koute/7391344 - res = SDL_Init(SDL_INIT_VIDEO); - if (res == -1) return 3; - atexit(SDL_Quit); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 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_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - - // Initialize OpenGL - //shm->ge.gl_win = SDL_CreateWindow("GL Debug", SDL_WINDOWPOS_CENTERED, 0, FBUF_W, FBUF_H, sdl_win_flags); - - res = SDL_CreateWindowAndRenderer(FBUF_W, FBUF_H, sdl_win_flags, &shm->ge.gl_win, &shm->ge.gl_rndr); - if (res == -1) return 4; - SDL_SetWindowTitle(shm->ge.gl_win, "GL debug"); - res = SDL_GetRendererInfo(shm->ge.gl_rndr, &renderer_info); - if (res < 0) return 5; - if (!(renderer_info.flags & SDL_RENDERER_ACCELERATED)) return 6; - if (!(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE)) return 7; - shm->ge.gl_target = SDL_CreateTexture(shm->ge.gl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FBUF_W, FBUF_H); - if (shm->ge.gl_target == NULL) return 9; - shm->ge.gl_ctx = SDL_GL_CreateContext(shm->ge.gl_win); - if (shm->ge.gl_ctx == NULL) return 11; -/* - glBindFramebuffer(GL_FRAMEBUFFER,0); - glClearColor(0,0,0,1); - glClear(GL_COLOR_BUFFER_BIT); - SDL_GL_SwapWindow(shm->ge.gl_win); -*/ - while (!shm->done) { - alarm(1); - SEM_WAIT(&shm->worker_gl_can_render,10); - alarm(0); - - if (!shm->paused && !skip) { - // init / free if scene transition - if (lastscene != shm->scene) { - switch(lastscene) { - case 0: scene00_free_gl(&shm->ge, &shm->s00e); break; - case 1: scene01_free_gl(&shm->ge, &shm->s01e); break; - case 2: scene02_free_gl(&shm->ge, &shm->s02e); break; - } - } - while (lastscene != shm->scene) { - shm->ge.sdl_ticks = SDL_GetTicks(); - shm->ge.sc_framecount = 0; - switch(shm->scene) { - case 0: res = scene00_init_gl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_init_gl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_init_gl(&shm->ge, &shm->s02e); break; - } - // If scene init fail, skip to the next one - if (res) SCENE_NEXT; else lastscene = shm->scene; - } - - // Compute current scene frame (gl part) - switch(shm->scene) { - case 0: res = scene00_next_gl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_next_gl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_next_gl(&shm->ge, &shm->s02e); break; - } - if (res) SCENE_NEXT; - } - if (skip) skip = 0; - -#ifdef DEBUG - // Event handling for the GL window (debug purposes) - while(SDL_PollEvent(&gl_ev)) { - switch(gl_ev.type) { - case SDL_QUIT: - shm->done = 1; - break; - case SDL_KEYDOWN: - switch(gl_ev.key.keysym.sym) { - case SDLK_q: shm->done = 1; break; - case SDLK_p: shm->paused = !shm->paused; break; - case SDLK_ESCAPE: SCENE_NEXT; break; - } - break; - default: - break; - } - } -#endif - SEM_POST(&shm->parent_can_read_result, 11); - } - - SDL_DestroyTexture(shm->ge.gl_target); - SDL_GL_DeleteContext(shm->ge.gl_ctx); - SDL_DestroyWindow(shm->ge.gl_win); - - return 0; -} -- cgit v1.2.3