From 25effd17ef1a1a05d671382b9a51be29734226a0 Mon Sep 17 00:00:00 2001
From: Ludovic Pouzenc <ludovic@pouzenc.fr>
Date: Sat, 7 Sep 2019 10:49:21 +0200
Subject: Multi-process done. GL has to be done cleanly now.

---
 src/main.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 79 insertions(+), 11 deletions(-)

(limited to 'src/main.c')

diff --git a/src/main.c b/src/main.c
index 9b151b1..d519034 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,8 +32,18 @@
 #include <stdint.h>    // uint32_t
 #include <stdio.h>     // printf()
 
-
+#ifdef DEBUG
 #define TRACE(hint) printf("%s(): %s\n", __func__, hint)
+#else
+#define TRACE(hint)
+#endif
+
+#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)
 
@@ -42,13 +52,13 @@
 
 #define SEM_POST(sem,errcode) \
 	do { \
-		/* printf("%s(): sem_post(%s,%i)\n", __func__, #sem, errcode); */ \
+		TRACE_SEM(sem,"sem_post",""); \
 		if ( sem_post(sem) == -1 ) { return errcode; } \
 	} while(0)
 
 #define SEM_WAIT(sem,errcode) \
 	do { \
-		/* printf("%s(): sem_wait(%s,%i) call\n", __func__, #sem, errcode); */\
+		TRACE_SEM(sem,"sem_wait","call"); \
 		while ( sem_wait(sem) == -1 ) { \
 			switch(errno) { \
 				case EINTR: \
@@ -58,7 +68,7 @@
 					return errcode; \
 			} \
 		} \
-		/* printf("%s(): sem_wait(%s,%i) done\n", __func__, #sem, errcode); */\
+		TRACE_SEM(sem,"sem_wait","done"); \
 	} while(0)
 
 typedef struct {
@@ -140,7 +150,6 @@ int parent() {
 			// init / free if scene transition
 			if ( lastscene != shm->scene ) {
 				switch(lastscene) {
-					//FIXME call free_gl and free_sdl in respective processes too
 					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;
@@ -150,7 +159,6 @@ int parent() {
 				shm->ge.sdl_ticks = SDL_GetTicks();
 				shm->ge.sc_framecount = 0;
 				switch(shm->scene) {
-					//FIXME call init_gl and init_sdl in respective processes too
 					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;
@@ -220,8 +228,8 @@ int parent() {
 }
 
 int worker_sdl() {
-	int res;
-	Uint32 sdl_win_flags = 0; //XXX for final version, consider sdl_win_flags = SDL_WINDOW_HIDDEN;
+	int lastscene=-1, res;
+	Uint32 sdl_win_flags = 0; //XXX for final version, consider adding SDL_WINDOW_HIDDEN
 	SDL_RendererInfo renderer_info;
 	SDL_Event sdl_ev;
 
@@ -247,6 +255,30 @@ int worker_sdl() {
 		//FIXME change for TRYWAIT for event handling (+delay)
 		SEM_WAIT(&shm->worker_sdl_can_render,20);
 
+		if (!shm->paused) {
+			// 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;
+			}
+		}
+
+		TRACE("before next_sdl");
+		printf("DEBUG shm->scene : %i\n", shm->scene);
 		// Compute current scene frame (sdl part)
 		switch(shm->scene) {
 			case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break;
@@ -254,6 +286,7 @@ int worker_sdl() {
 			case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break;
 		}
 		if (res) SCENE_NEXT;
+		TRACE("after next_sdl");
 
 		// Event handling for the SDL window (debug purposes)
 		while(SDL_PollEvent(&sdl_ev)) {
@@ -272,8 +305,10 @@ int worker_sdl() {
 					break;
 			}
 		}
+		TRACE("after SDL_PollEvent loop");
 
 		SEM_POST(&shm->parent_can_read_result, 21);
+		TRACE("after sem_post");
 	}
 
 	SDL_DestroyRenderer(shm->ge.sdl_rndr);
@@ -284,8 +319,9 @@ int worker_sdl() {
 }
 
 int worker_gl() {
-	int res;
-	//Uint32 sdl_win_flags = SDL_WINDOW_OPENGL;
+	int lastscene=-1, res;
+	Uint32 sdl_win_flags = SDL_WINDOW_OPENGL; //XXX for final version, consider adding SDL_WINDOW_HIDDEN
+	SDL_RendererInfo renderer_info;
 	SDL_Event gl_ev;
 
 	TRACE("call");
@@ -307,7 +343,17 @@ int worker_gl() {
 	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_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
+	//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;
 
@@ -315,6 +361,28 @@ int worker_gl() {
 		//FIXME change for TRYWAIT for event handling (+delay)
 		SEM_WAIT(&shm->worker_gl_can_render,10);
 
+		if (!shm->paused) {
+			// 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;
-- 
cgit v1.2.3