summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c198
-rw-r--r--src/main.h23
-rw-r--r--src/scene00.c73
-rw-r--r--src/scene00.h12
-rw-r--r--src/scene01.c49
-rw-r--r--src/scene01.h12
-rw-r--r--src/scene02.c42
-rw-r--r--src/scene02.h12
8 files changed, 421 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..a73bf44
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,198 @@
+/*
+ * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement
+ * Copyright (C) 2019 Ludovic Pouzenc <ludovic@pouzenc.fr>
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ */
+#include "main.h"
+#include "scene00.h"
+#include "scene01.h"
+#include "scene02.h"
+#define SCENE_COUNT 3
+#define SCENE_NEXT do { scene = (scene+1)%SCENE_COUNT; } while(0)
+
+#define EXPR_MIN_SIZE ( ge.w<80 || ge.h<25 )
+#define TEXT_MIN_SIZE "80x25"
+
+int main(void)
+{
+ int done=0, lastscene=-1, scene=0, paused=0, res;
+ Uint32 sdl_win_flags = SDL_WINDOW_OPENGL;
+ graphical_env_t ge;
+ scene00_env_t s00e;
+ scene01_env_t s01e;
+ scene02_env_t s02e;
+
+ caca_event_t caca_ev;
+ SDL_RendererInfo renderer_info;
+ SDL_Event sdl_ev;
+
+ // Initialize libcaca (http://caca.zoy.org/doxygen/libcaca/caca_8h.html)
+ ge.dp = caca_create_display(NULL);
+ if(!ge.dp) return 1;
+ caca_set_display_title(ge.dp, "demoscene-eo");
+ caca_set_display_time(ge.dp, 16666); // 1e6µs/60 = 16666.66... It is ~60 fps
+ ge.cv = caca_get_canvas(ge.dp);
+
+ ge.d = caca_create_dither(32, 256, 256, 256*4, 0x00ff0000, 0x0000ff00, 0x000000ff, 0);
+ if ( !ge.d ) return 2;
+ caca_set_dither_color(ge.d, "16");
+
+ // 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;
+ 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 );
+
+ //XXX for final version, consider sdl_win_flags |= SDL_WINDOW_HIDDEN;
+ res = SDL_CreateWindowAndRenderer(256, 256, sdl_win_flags, &ge.sdl_win, &ge.sdl_rndr);
+ if ( res == -1) return 4;
+ SDL_SetWindowTitle(ge.sdl_win, "SDL/GL debug");
+ res = SDL_GetRendererInfo(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;
+ ge.sdl_target = SDL_CreateTexture(ge.sdl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 256, 256);
+ if ( ge.sdl_target == NULL ) return 9;
+ ge.raw_target = malloc(256*256*4);
+ if ( ge.raw_target == NULL ) return 10;
+ ge.gl_ctx = SDL_GL_CreateContext(ge.sdl_win);
+ if ( ge.gl_ctx == NULL ) return 11;
+
+
+ // Initialize OpenGL
+ glShadeModel(GL_SMOOTH);
+ glClearDepth(1.0f);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ glDisable(GL_TEXTURE_2D);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT);
+ glViewport(0, 0, (GLsizei)256, (GLsizei)256);
+ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 1.0f, 0.1f, 100.0f); // 1.0f==ratio
+ glMatrixMode(GL_MODELVIEW); glLoadIdentity();
+
+ // Main libcaca loop for caca window (OpenGL could be used in sceneN_next())
+ ge.framecount=0;
+ do {
+ // Check canvas size at every frame because of unreliable CACA_EVENT_RESIZE
+ ge.w = caca_get_canvas_width(ge.cv);
+ ge.h = caca_get_canvas_height(ge.cv);
+ if ( EXPR_MIN_SIZE ) {
+ caca_set_color_ansi(ge.cv, CACA_BLACK, CACA_WHITE);
+ caca_put_str(ge.cv, 0, 0, "Need a minimum of " TEXT_MIN_SIZE " terminal");
+ } else if (!paused) {
+ // init / free if scene transition
+ if ( lastscene != scene ) {
+ switch(lastscene) {
+ case 0: scene00_free(&ge, &s00e); break;
+ case 1: scene01_free(&ge, &s01e); break;
+ case 2: scene02_free(&ge, &s02e); break;
+ }
+ }
+ while ( lastscene != scene ) {
+ ge.sdl_ticks = SDL_GetTicks();
+ ge.sc_framecount = 0;
+ switch(scene) {
+ case 0: res = scene00_init(&ge, &s00e); break;
+ case 1: res = scene01_init(&ge, &s01e); break;
+ case 2: res = scene02_init(&ge, &s02e); break;
+ }
+ // If scene init fail, skip to the next one
+ if (res) SCENE_NEXT; else lastscene = scene;
+ }
+ // Compute current scene0 frame
+ ge.sdl_ticks = SDL_GetTicks(); // This value wraps if the program runs for more than ~49 days
+ switch(scene) {
+ case 0: res = scene00_next(&ge, &s00e); break;
+ case 1: res = scene01_next(&ge, &s01e); break;
+ case 2: res = scene02_next(&ge, &s02e); break;
+ }
+ if (res) SCENE_NEXT;
+ ge.framecount++;
+ ge.sc_framecount++;
+ }
+ // Display it
+ caca_refresh_display(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(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:
+ done = 1;
+ break;
+ case CACA_EVENT_KEY_PRESS:
+ switch(caca_get_event_key_ch(&caca_ev)) {
+ case 'q': done = 1; break;
+ case 'p': paused = !paused; break;
+ case CACA_KEY_ESCAPE: SCENE_NEXT; break;
+ }
+ break;
+ /* On Debian 10, no CACA_EVENT_RESIZE 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;
+ }
+ }
+ // Event handling for the SDL/GL window (debug purposes)
+ while(SDL_PollEvent(&sdl_ev)) {
+ switch(sdl_ev.type) {
+ case SDL_QUIT:
+ done = 1;
+ break;
+ case SDL_KEYDOWN:
+ switch(sdl_ev.key.keysym.sym) {
+ case SDLK_q: done = 1; break;
+ case SDLK_p: paused = !paused; break;
+ case SDLK_ESCAPE: SCENE_NEXT; break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ } while(!done);
+
+ caca_free_dither(ge.d);
+ caca_free_display(ge.dp);
+ ge.cv=NULL;
+ SDL_GL_DeleteContext(ge.gl_ctx);
+ SDL_DestroyTexture(ge.sdl_target);
+ SDL_DestroyRenderer(ge.sdl_rndr);
+ SDL_DestroyWindow(ge.sdl_win);
+ SDL_Quit();
+ return 0;
+}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000..b2b0a6e
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,23 @@
+#ifndef MAIN_H_INCLUDED
+#define MAIN_H_INCLUDED
+
+#include <caca.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_opengl.h>
+#include <GL/glu.h>
+
+typedef struct {
+ caca_display_t *dp;
+ caca_canvas_t *cv;
+ caca_dither_t *d;
+ int w, h; // caca terminal size in characters
+ SDL_Window* sdl_win;
+ SDL_Renderer *sdl_rndr;
+ SDL_Texture *sdl_target;
+ void *raw_target;
+ SDL_GLContext gl_ctx;
+ Uint32 sdl_ticks;
+ Uint32 framecount;
+ Uint32 sc_framecount;
+} graphical_env_t;
+#endif
diff --git a/src/scene00.c b/src/scene00.c
new file mode 100644
index 0000000..746db29
--- /dev/null
+++ b/src/scene00.c
@@ -0,0 +1,73 @@
+/*
+ * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement
+ * Copyright (C) 2019 XXXXXX XXXXXXX <xxxxxx@xxxxxx.fr>
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ */
+#include "scene00.h"
+
+int scene00_init(graphical_env_t *ge, scene00_env_t *se) {
+ SDL_Surface *bmpSurf = SDL_LoadBMP("./res/eo1.bmp");
+ se->eo1 = SDL_CreateTextureFromSurface(ge->sdl_rndr, bmpSurf);
+ SDL_FreeSurface(bmpSurf);
+
+ return 0;
+}
+
+void scene00_free(graphical_env_t *ge, scene00_env_t *se) {
+ SDL_DestroyTexture(se->eo1); se->eo1=NULL;
+}
+
+int scene00_next(graphical_env_t *ge, scene00_env_t *se) {
+ // Shorthands
+ caca_canvas_t *cv = ge->cv;
+ int w = ge->w, h = ge->h;
+ Uint32 frame = ge->sc_framecount;
+ SDL_Renderer *r = ge->sdl_rndr;
+ // Local vars
+ int res;
+
+ // https://gist.github.com/Twinklebear/8265888
+ // https://forums.libsdl.org/viewtopic.php?p=51634
+
+ // Render all the stuff on target texture
+ SDL_SetRenderTarget(r, ge->sdl_target);
+ SDL_RenderCopy(r, se->eo1, NULL, NULL);
+ // [...]
+
+ // Copy the SDL screen to SDL debug window (and display it, not mandatory)
+ SDL_SetRenderTarget(r, NULL);
+ SDL_RenderCopy(r, ge->sdl_target, NULL, NULL);
+ SDL_RenderPresent(r);
+
+ // Download the rendered texture from videocard to main memory
+ res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4);
+
+ // "convert" the raw pixel stream to ASCII art on caca canevas
+ if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+
+ // Add things on top of caca canvas
+ caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE);
+ caca_put_str(cv, (w-17)/2, h/2, "This is a message");
+ caca_draw_line(cv,6,6,w-14,11, '*');
+ caca_draw_thin_line(cv,frame%10,frame%10,w-10+frame%10,h-10+frame%10);
+
+ if ( frame >= 100 ) {
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/scene00.h b/src/scene00.h
new file mode 100644
index 0000000..b1c9d9d
--- /dev/null
+++ b/src/scene00.h
@@ -0,0 +1,12 @@
+#ifndef SCENE00_H_INCLUDED
+#define SCENE00_H_INCLUDED
+
+#include "main.h"
+typedef struct {
+ SDL_Texture *eo1;
+} scene00_env_t;
+
+int scene00_init(graphical_env_t *ge, scene00_env_t *se);
+void scene00_free(graphical_env_t *ge, scene00_env_t *se);
+int scene00_next(graphical_env_t *ge, scene00_env_t *se);
+#endif
diff --git a/src/scene01.c b/src/scene01.c
new file mode 100644
index 0000000..2b3e9f5
--- /dev/null
+++ b/src/scene01.c
@@ -0,0 +1,49 @@
+/*
+ * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement
+ * Copyright (C) 2019 XXXXXX XXXXXXX <xxxxxx@xxxxxx.fr>
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ */
+#include "scene01.h"
+
+int scene01_init(graphical_env_t *ge, scene01_env_t *se) {
+ return 0;
+}
+
+void scene01_free(graphical_env_t *ge, scene01_env_t *se) {
+}
+
+int scene01_next(graphical_env_t *ge, scene01_env_t *se) {
+ // Shorthands
+ caca_canvas_t *cv = ge->cv;
+ int w = ge->w, h = ge->h;
+ Uint32 frame = ge->sc_framecount;
+
+ //XXX remove me
+ ((Uint32 *)ge->raw_target)[frame%(256*256)]=frame<<((frame%3)*8);
+
+ caca_clear_canvas(cv);
+ caca_set_dither_gamma(ge->d, (100-frame%100)/100.0);
+ caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+
+ caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK);
+ caca_put_str(cv, (w-17)/2, h/2, "This is a message");
+
+ if ( frame >= 300 ) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/scene01.h b/src/scene01.h
new file mode 100644
index 0000000..1f22de7
--- /dev/null
+++ b/src/scene01.h
@@ -0,0 +1,12 @@
+#ifndef SCENE01_H_INCLUDED
+#define SCENE01_H_INCLUDED
+
+#include "main.h"
+typedef struct {
+
+} scene01_env_t;
+
+int scene01_init(graphical_env_t *ge, scene01_env_t *se);
+void scene01_free(graphical_env_t *ge, scene01_env_t *se);
+int scene01_next(graphical_env_t *ge, scene01_env_t *se);
+#endif
diff --git a/src/scene02.c b/src/scene02.c
new file mode 100644
index 0000000..1989bf0
--- /dev/null
+++ b/src/scene02.c
@@ -0,0 +1,42 @@
+/*
+ * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement
+ * Copyright (C) 2019 XXXXXX XXXXXXX <xxxxxx@xxxxxx.fr>
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ */
+#include "scene02.h"
+
+int scene02_init(graphical_env_t *ge, scene02_env_t *se) {
+ return 0;
+}
+
+void scene02_free(graphical_env_t *ge, scene02_env_t *se) {
+}
+
+int scene02_next(graphical_env_t *ge, scene02_env_t *se) {
+ // Shorthands
+ caca_canvas_t *cv = ge->cv;
+ //int w = ge->w, h = ge->h;
+ Uint32 frame = ge->sc_framecount;
+
+ caca_clear_canvas(cv);
+
+ if ( frame >= 100 ) {
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/scene02.h b/src/scene02.h
new file mode 100644
index 0000000..49abbfb
--- /dev/null
+++ b/src/scene02.h
@@ -0,0 +1,12 @@
+#ifndef SCENE02_H_INCLUDED
+#define SCENE02_H_INCLUDED
+
+#include "main.h"
+typedef struct {
+
+} scene02_env_t;
+
+int scene02_init(graphical_env_t *ge, scene02_env_t *se);
+void scene02_free(graphical_env_t *ge, scene02_env_t *se);
+int scene02_next(graphical_env_t *ge, scene02_env_t *se);
+#endif