/** * @brief Updates the sonuds removing obsolete ones and such. * * @return 0 on success. */ int sound_update( double dt ) { alVoice *v, *tv; /* Update music if needed. */ music_update(dt); if (sound_disabled) return 0; /* System update. */ sound_sys_update(); if (voice_active == NULL) return 0; voiceLock(); /* The actual control loop. */ for (v=voice_active; v!=NULL; v=v->next) { /* Run first to clear in same iteration. */ sound_sys_updateVoice( v ); /* Destroy and toss into pool. */ if ((v->state == VOICE_STOPPED) || (v->state == VOICE_DESTROY)) { /* Remove from active list. */ tv = v->prev; if (tv == NULL) { voice_active = v->next; if (voice_active != NULL) voice_active->prev = NULL; } else { tv->next = v->next; if (tv->next != NULL) tv->next->prev = tv; } /* Add to free pool. */ v->next = voice_pool; v->prev = NULL; voice_pool = v; if (v->next != NULL) v->next->prev = v; /* Avoid loop blockage. */ v = (tv != NULL) ? tv->next : voice_active; if (v == NULL) break; } } voiceUnlock(); return 0; }
/** * A background task that calls all of the update functions. * * The order of the updates here is done from most important to * least important. Note that if an update request is made while * this task is running, it can cause the task to be *restarted*, so * it is possible for the logic at the bottom of the function to * be starved temporarily. */ static void effect_update_task (void) { /* Display and music are always updated, including during attract mode */ deff_update (); music_update (); /* Lamp update is used for multiplexing different meanings to playfield lamps; this only makes sense in the context of a game. */ if (in_live_game) { /* Sleep a bit to avoid starving other tasks */ task_sleep (TIME_33MS); callset_invoke (lamp_update); } /* Update the start button lamp */ if (!in_test) lamp_start_update (); task_exit (); }
/** * @brief Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { double offset; /* distance from bottom of the top line. */ double line_height; /* # pixels per line. */ int lines_per_screen; /* max appearing lines on the screen. */ scroll_buf_t *sb_arr; /* array of lines to render. */ scroll_buf_t *sb_list; /* list " " " " */ double vel = 16.; /* velocity: speed of text. */ int stop = 0; /* stop the intro. */ unsigned int tcur, tlast; /* timers. */ double delta; /* time diff from last render to this one. */ int line_index = 0; /* index into the big list of intro lines. */ intro_img_t side_image; /* image to go along with the text. */ intro_img_t transition; /* image for transitioning. */ /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Enable keyrepeat just for the intro. */ SDL_EnableKeyRepeat( conf.repeat_delay, conf.repeat_freq ); /* Do a few calculations to figure out how many lines can be present on the screen at any given time. */ line_height = (double)intro_font.h * 1.3; lines_per_screen = (int)(SCREEN_H / line_height + 1.5); /* round up + 1 */ sb_arr = (scroll_buf_t*)malloc( sizeof(scroll_buf_t) * lines_per_screen ); /* Force the first line to be loaded immediately. */ offset = line_height; /* Create a cycle of lines. */ sb_list = arrange_scroll_buf( sb_arr, lines_per_screen ); /* Unset the side image. */ initialize_image( &side_image ); initialize_image( &transition ); tlast = SDL_GetTicks(); while (!stop) { tcur = SDL_GetTicks(); delta = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Increment position. */ offset += vel * delta; while (! (offset < line_height)) { /* One line has scrolled off, and another one on. */ if (line_index < intro_nlines) { switch (intro_lines[line_index][0]) { case 't': /* plain ol' text. */ sb_list->text = &intro_lines[line_index][1]; offset -= line_height; sb_list = sb_list->next; break; case 'i': /* fade in image. */ intro_fade_image_in( &side_image, &transition, &intro_lines[line_index][1] ); break; case 'o': /* fade out image. */ if (NULL == side_image.tex) { WARN("Tried to fade out without an image." ); break; } side_image.fade_rate = -0.1; side_image.c.a = 0.99; break; default: /* unknown. */ break; } ++line_index; } else { sb_list->text = NULL; offset -= line_height; sb_list = sb_list->next; } } /* while (offset > line_height) */ /* Fade the side image. */ if (side_image.tex != NULL && side_image.c.a < 1.0) { side_image.c.a += delta * vel * side_image.fade_rate; if (transition.tex != NULL && transition.fade_rate > 0.0) { transition.c.a += delta * vel * transition.fade_rate; } if (side_image.c.a > 1.0) { /* Faded in... */ side_image.c.a = 1.0; side_image.fade_rate = 0.0; } else if (side_image.c.a < 0.0) { /* Faded out... */ gl_freeTexture( side_image.tex ); if (transition.tex != NULL) { side_image.tex = transition.tex; side_image.c.a = transition.c.a; side_image.y = transition.y; side_image.fade_rate = 0.1; transition.tex = NULL; transition.c.a = 1.0; } else { side_image.c.a = 1.0; side_image.tex = NULL; side_image.fade_rate = 0.0; } } } /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Only thing we actually care about updating is music. */ music_update( 0. ); /* Draw text. */ stop = intro_draw_text( sb_list, offset, line_height ); if (NULL != side_image.tex) { /* Draw the image next to the text. */ gl_blitScale( side_image.tex, side_image.x, side_image.y, side_image.tex->w, side_image.tex->h, &side_image.c ); } if (NULL != transition.tex && transition.c.a > 0.0) { /* Draw the image in transition. */ gl_blitScale( transition.tex, transition.x, transition.y, transition.tex->w, transition.tex->h, &transition.c ); } /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ /* Handle user events. */ intro_event_handler( &stop, &offset, &vel ); } /* while (!stop) */ /* free malloc'd memory. */ free( sb_arr ); if (NULL != side_image.tex) { gl_freeTexture( side_image.tex ); } if (NULL != transition.tex) { gl_freeTexture( transition.tex ); } /* Disable intro's key repeat. */ SDL_EnableKeyRepeat( 0, 0 ); /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }
/** * @brief Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { int i, max; unsigned int tcur, tlast; double dt; double x, y, vel; double offset; double density; SDL_Event event; /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Calculate velocity. */ density = ((double)intro_length / (double)intro_nlines); /* char / line */ density /= (double)intro_font.h; /* char / pixel */ vel = INTRO_SPEED / density; /* (char / s) * (pixel / char) = pixel / s */ /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Prepare for intro loop. */ x = 100.; y = 0.; tlast = SDL_GetTicks(); offset = 0.; max = intro_nlines + SCREEN_H / ((intro_font.h + 5.)); while (1) { /* Get delta tick in seconds. */ tcur = SDL_GetTicks(); dt = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Handle events. */ while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: /* Escape skips directly. */ if (event.key.keysym.sym == SDLK_ESCAPE) offset = max * (intro_font.h + 5.); /* Only Handle space from here down. */ else if (!nstd_isspace(event.key.keysym.sym)) break; /* Purpose fallthrough. */ case SDL_JOYBUTTONDOWN: offset += 250.; default: break; } } /* Increment position. */ offset += vel * dt; /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Draw the text. */ i = (int)(offset / (intro_font.h + 5.)); if (i > max) /* Out of lines. */ break; y = offset - (i+1) * (intro_font.h + 5.); while (i >= 0) { /* Skip in line isn't valid. */ if (i >= intro_nlines) { i--; y += intro_font.h + 5.; continue; } gl_print( &intro_font, x, y, &cConsole, intro_lines[i] ); /* Increment line and position. */ i--; y += intro_font.h + 5.; } /* Only thing we actually care about updating is music. */ music_update(); /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ } /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }