void JE_outTextGlow( SDL_Surface * screen, int x, int y, const char *s ) { int16_t z; uint8_t c = 15; if (warningRed) { c = 7; } JE_outTextAdjust(screen, x - 1, y, s, 0, -12, textGlowFont, false); JE_outTextAdjust(screen, x, y - 1, s, 0, -12, textGlowFont, false); JE_outTextAdjust(screen, x + 1, y, s, 0, -12, textGlowFont, false); JE_outTextAdjust(screen, x, y + 1, s, 0, -12, textGlowFont, false); if (frameCountMax > 0) for (z = 1; z <= 12; z++) { setjasondelay(frameCountMax); JE_outTextAdjust(screen, x, y, s, c, z - 10, textGlowFont, false); if (JE_anyButton()) { frameCountMax = 0; } NETWORK_KEEP_ALIVE(); JE_showVGA(); wait_delay(); } for (z = (frameCountMax == 0) ? 6 : 12; z >= textGlowBrightness; z--) { setjasondelay(frameCountMax); JE_outTextAdjust(screen, x, y, s, c, z - 10, textGlowFont, false); if (JE_anyButton()) { frameCountMax = 0; } NETWORK_KEEP_ALIVE(); JE_showVGA(); wait_delay(); } textGlowBrightness = 6; }
void JE_playAnim( const char *animfile, uint8_t startingframe, uint8_t speed ) { uint32_t i; int pageNum; if (JE_loadAnim(animfile) != 0) { return; /* Failed to open or process file */ } /* Blank screen */ JE_clr256(VGAScreen); JE_showVGA(); /* re FileHeader.nRecords-1: It's -1 in the pascal too. * The final frame is a delta of the first, and we don't need that. * We could also, if we ever ended up needing to loop anis, check * the bools in the header to see if we should render the last * frame. But that's never going to be encessary :) */ for (i = startingframe; i < FileHeader.nRecords-1; i++) { /* Handle boring crap */ setjasondelay(speed); /* Load required frame. The loading function is smart enough to not re-load an already loaded frame */ pageNum = JE_findPage(i); if(pageNum == -1) { break; } if (JE_loadPage(pageNum) != 0) { break; } /* render frame. */ if (JE_renderFrame(i) != 0) { break; } JE_showVGA(); /* Return early if user presses a key */ service_SDL_events(true); if (newkey) { break; } /* Wait until we need the next frame */ NETWORK_KEEP_ALIVE(); wait_delay(); } JE_closeAnim(); }
void JE_fadeColors( Palette fromColors, Palette toColors, unsigned int startColor, unsigned int numColors, int numSteps ) { for (int s = 0; s <= numSteps; ++s) { setdelay(1); for (unsigned int i = startColor; i <= startColor + numColors; ++i) { //long difference = toColors[i].r - fromColors[i].r; //long each_step = difference / static_cast<long>(numSteps); //double steps_so_far = each_step * s; //palette[i].r = static_cast<Uint8>(steps_so_far) + fromColors[i].r; //palette[i].r = (toColors[i].r - fromColors[i].r) / numSteps * s + fromColors[i].r; palette[i].r = fromColors[i].r + (toColors[i].r - fromColors[i].r) * s / numSteps; palette[i].g = fromColors[i].g + (toColors[i].g - fromColors[i].g) * s / numSteps; palette[i].b = fromColors[i].b + (toColors[i].b - fromColors[i].b) * s / numSteps; rgb_palette[i] = SDL_MapRGB(display_surface->format, palette[i].r, palette[i].g, palette[i].b); yuv_palette[i] = rgb_to_yuv(palette[i]); } JE_showVGA(); wait_delay(); } }
// captures joystick input for configuring assignments // returns false if non-joystick input was detected // TODO: input from joystick other than the one being configured probably should not be ignored bool detect_joystick_assignment( int j, Joystick_assignment *assignment ) { // get initial joystick state to compare against to see if anything was pressed const int axes = SDL_JoystickNumAxes(joystick[j].handle); Sint16 *axis = malloc(axes * sizeof(*axis)); for (int i = 0; i < axes; i++) axis[i] = SDL_JoystickGetAxis(joystick[j].handle, i); const int buttons = SDL_JoystickNumButtons(joystick[j].handle); Uint8 *button = malloc(buttons * sizeof(*button)); for (int i = 0; i < buttons; i++) button[i] = SDL_JoystickGetButton(joystick[j].handle, i); const int hats = SDL_JoystickNumHats(joystick[j].handle); Uint8 *hat = malloc(hats * sizeof(*hat)); for (int i = 0; i < hats; i++) hat[i] = SDL_JoystickGetHat(joystick[j].handle, i); bool detected = false; do { setjasondelay(1); SDL_JoystickUpdate(); for (int i = 0; i < axes; ++i) { Sint16 temp = SDL_JoystickGetAxis(joystick[j].handle, i); if (abs(temp - axis[i]) > joystick_analog_max * 2 / 3) { assignment->type = AXIS; assignment->num = i; assignment->negative_axis = temp < axis[i]; detected = true; break; } } for (int i = 0; i < buttons; ++i) { Uint8 new_button = SDL_JoystickGetButton(joystick[j].handle, i), changed = button[i] ^ new_button; if (!changed) continue; if (new_button == 0) // button was released { button[i] = new_button; } else // button was pressed { assignment->type = BUTTON; assignment->num = i; detected = true; break; } } for (int i = 0; i < hats; ++i) { Uint8 new_hat = SDL_JoystickGetHat(joystick[j].handle, i), changed = hat[i] ^ new_hat; if (!changed) continue; if ((new_hat & changed) == SDL_HAT_CENTERED) // hat was centered { hat[i] = new_hat; } else { assignment->type = HAT; assignment->num = i; assignment->x_axis = changed & (SDL_HAT_LEFT | SDL_HAT_RIGHT); assignment->negative_axis = changed & (SDL_HAT_LEFT | SDL_HAT_UP); detected = true; } } service_SDL_events(true); JE_showVGA(); wait_delay(); } while (!detected && !newkey && !newmouse); free(axis); free(button); free(hat); return detected; }
/* Text is an array of strings terminated by a NULL */ void scroller_sine( const struct about_text_type text[] ) { bool ale = mt_rand() % 2; int visible_lines = vga_height / LINE_HEIGHT + 1; int current_line = -visible_lines; int y = 0; bool fade_in = true; struct coin_type { int x, y, vel, type, cur_frame; bool backwards; } coins[MAX_COINS]; struct { int x, y, ay, vx, vy; } beer[MAX_BEER]; if (ale) { memset(beer, 0, sizeof(beer)); } else { for (int i = 0; i < MAX_COINS; i++) { coins[i].x = mt_rand() % (vga_width - 12); coins[i].y = mt_rand() % (vga_height - 20 - 14); coins[i].vel = (mt_rand() % 4) + 1; coins[i].type = mt_rand() % COUNTOF(coin_defs); coins[i].cur_frame = mt_rand() % coin_defs[coins[i].type].frame_count; coins[i].backwards = false; } } fade_black(10); wait_noinput(true, true, true); play_song(40); // BEER while (!JE_anyButton()) { setdelay(3); JE_clr256(VGAScreen); if (!ale) { for (int i = 0; i < MAX_COINS/2; i++) { struct coin_type *coin = &coins[i]; blit_sprite2(VGAScreen, coin->x, coin->y, eShapes5, coin_defs[coin->type].shape_num + coin->cur_frame); } } for (int i = 0; i < visible_lines; i++) { if (current_line + i >= 0) { if (text[current_line + i].text == NULL) { break; } int line_x = VGAScreen->w / 2; int line_y = i * LINE_HEIGHT - y; // smooths edges on sine-wave text if (text[i + current_line].effect & 0x20) { draw_font_hv(VGAScreen, line_x + 1, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -10); draw_font_hv(VGAScreen, line_x - 1, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -10); } draw_font_hv(VGAScreen, line_x, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -4); if (text[i + current_line].effect & 0x10) { for (int j = 0; j < LINE_HEIGHT; j++) { if (line_y + j >= 10 && line_y + j <= vga_height - 10) { int waver = sinf((((line_y + j) / 2) % 10) / 5.0f * M_PI) * 3; memmove(&((Uint8 *)VGAScreen->pixels)[VGAScreen->pitch * (line_y + j) + waver], &((Uint8 *)VGAScreen->pixels)[VGAScreen->pitch * (line_y + j)], VGAScreen->pitch); } } } } } if (++y == LINE_HEIGHT) { y = 0; if (current_line < 0 || text[current_line].text != NULL) ++current_line; else current_line = -visible_lines; } if (!ale) { for (int i = MAX_COINS/2; i < MAX_COINS; i++) { struct coin_type *coin = &coins[i]; blit_sprite2(VGAScreen, coin->x, coin->y, eShapes5, coin_defs[coin->type].shape_num + coin->cur_frame); } } fill_rectangle_xy(VGAScreen, 0, 0, vga_width - 1, 14, 0); fill_rectangle_xy(VGAScreen, 0, vga_height - 14, vga_width - 1, vga_height - 1, 0); if (!ale) { for (int i = 0; i < MAX_COINS; i++) { struct coin_type *coin = &coins[i]; if (coin->backwards) { coin->cur_frame--; } else { coin->cur_frame++; } if (coin->cur_frame == coin_defs[coin->type].frame_count) { if (coin_defs[coin->type].reverse_anim) { coin->backwards = true; coin->cur_frame -= 2; } else { coin->cur_frame = 0; } } if (coin->cur_frame == -1) { coin->cur_frame = 1; coin->backwards = false; } coin->y += coin->vel; if (coin->y > vga_height - 14) { coin->x = mt_rand() % (vga_width - 12); coin->y = 0; coin->vel = (mt_rand() % 4) + 1; coin->type = mt_rand() % COUNTOF(coin_defs); coin->cur_frame = mt_rand() % coin_defs[coin->type].frame_count; } } } else { for (uint i = 0; i < COUNTOF(beer); i++) { while (beer[i].vx == 0) { beer[i].x = mt_rand() % (vga_width - 24); beer[i].y = mt_rand() % (vga_height - 28 - 50); beer[i].vx = (mt_rand() % 5) - 2; } beer[i].vy++; if (beer[i].x + beer[i].vx > vga_width - 24 || beer[i].x + beer[i].vx < 0) // check if the beer hit the sides { beer[i].vx = -beer[i].vx; } beer[i].x += beer[i].vx; if (beer[i].y + beer[i].vy > vga_height - 28) // check if the beer hit the bottom { if ((beer[i].vy) < 8) // make sure the beer bounces! { beer[i].vy += mt_rand() % 2; } else if (beer[i].vy > 16) { // make sure the beer doesn't bounce too high beer[i].vy = 16; } beer[i].vy = -beer[i].vy + (mt_rand() % 3 - 1); beer[i].x += (beer[i].vx > 0 ? 1 : -1) * (i % 2 ? 1 : -1); } beer[i].y += beer[i].vy; blit_sprite2x2(VGAScreen, beer[i].x, beer[i].y, eShapes5, BEER_SHAPE); } } JE_showVGA(); if (fade_in) { fade_in = false; fade_palette(colors, 10, 0, 255); SDL_Color white = { 255, 255, 255 }; set_colors(white, 254, 254); } wait_delay(); } fade_black(10); }
void JE_jukeboxGo( void ) { JE_boolean weirdMusic, weirdCurrent; JE_byte weirdSpeed = 0; char tempStr[64]; JE_byte lastSong; JE_byte tempVolume; JE_boolean youStopped, drawText, quit, fade; weirdMusic = false; weirdCurrent = true; drawText = true; fx = false; fxNum = 1; lastSong = currentJukeboxSong; JE_fadeBlack(10); SDL_FillRect(VGAScreenSeg, NULL, 0x0); JE_showVGA(); JE_updateColorsFast(vga_palette); //JE_fadeColor(10); JE_starlib_init(); quit = false; fade = false; repeatedFade = false; tempVolume = tyrMusicVolume; youStopped = false; JE_wipeKey(); do { tempScreenSeg = VGAScreenSeg; if (weirdMusic) { if (delaycount2() == 0) { setjasondelay2(weirdSpeed); if (weirdCurrent) { JE_setVol(tempVolume / 2, fxVolume); } else { JE_setVol(tempVolume, fxVolume); } weirdCurrent = !weirdCurrent; } } if (repeated && !repeatedFade) { fade = true; repeatedFade = true; } if ( ( (repeated && !fade) || !playing) && !youStopped) { currentJukeboxSong = ( mt_rand() % MUSIC_NUM ); JE_playNewSong(); } setdelay(1); push_joysticks_as_keyboard(); service_SDL_events(true); JE_starlib_main(); if (lastSong != currentJukeboxSong) { lastSong = currentJukeboxSong; JE_bar(50, 190, 250, 198, 0); } if (drawText) { tempScreenSeg = VGAScreenSeg; if (fx) { sprintf(tempStr, "%d %s", fxNum, soundTitle[fxNum - 1]); JE_bar(50, 190, 250, 198, 0); JE_outText(JE_fontCenter(tempStr, TINY_FONT), 190, tempStr, 1, 4); } else { sprintf(tempStr, "%d %s", currentJukeboxSong, musicTitle[currentJukeboxSong - 1]); JE_outText(JE_fontCenter(tempStr, TINY_FONT), 190, tempStr, 1, 4); } tempScreenSeg = VGAScreenSeg; JE_outText(JE_fontCenter("Press ESC to quit the jukebox.", TINY_FONT), 170, "Press ESC to quit the jukebox.", 1, 0); tempScreenSeg = VGAScreenSeg; JE_outText(JE_fontCenter("Arrow keys change the song being played.", TINY_FONT), 180, "Arrow keys change the song being played.", 1, 0); } JE_showVGA(); wait_delay(); if (fade) { if (volumeActive) { if (tempVolume > 5) { tempVolume -= 2; JE_setVol(tempVolume, fxVolume); } else { fade = false; } } else if (speed < 0xE000) { speed += 0x800; } else { speed = 0xE000; fade = false; } JE_resetTimerInt(); JE_setTimerInt(); } if (JE_mousePosition(&x, &y) > 0 || button[0]) { quit = true; JE_wipeKey(); } if (newkey) { JE_newSpeed(); switch (lastkey_sym) { case SDLK_ESCAPE: /* quit jukebox */ case SDLK_q: quit = true; break; case SDLK_r: /* restart song */ JE_jukebox_selectSong(1); break; case SDLK_n: /* toggle continuous play */ continuousPlay = !continuousPlay; break; case SDLK_v: volumeActive = !volumeActive; break; case SDLK_t: /* No idea what this is doing -- possibly resetting to default speed? */ speed = 0x4300; JE_resetTimerInt(); JE_setTimerInt(); break; case SDLK_f: fade = !fade; break; case SDLK_COMMA: /* dec sound effect */ fxNum = (fxNum - 1 < 1) ? SOUND_NUM + 9 : fxNum - 1; break; case SDLK_PERIOD: /* inc sound effect */ fxNum = (fxNum + 1 > SOUND_NUM + 9) ? 1 : fxNum + 1; break; case SDLK_SLASH: /* switch to sfx mode */ fx = !fx; break; case SDLK_SEMICOLON: JE_playSampleNum(fxNum); break; case SDLK_RETURN: currentJukeboxSong++; JE_playNewSong(); youStopped = false; break; case SDLK_s: JE_jukebox_selectSong(0); youStopped = true; break; case SDLK_w: if (!weirdMusic) { weirdMusic = true; weirdSpeed = 10; } else if (weirdSpeed > 1) { weirdSpeed--; } else { weirdMusic = false; if (!fade) { JE_setVol(tempVolume, fxVolume); } } break; case SDLK_SPACE: drawText = !drawText; if (!drawText) { JE_bar(30, 170, 270, 198, 0); } break; case SDLK_LEFT: case SDLK_UP: currentJukeboxSong--; JE_playNewSong(); youStopped = false; break; case SDLK_RIGHT: case SDLK_DOWN: currentJukeboxSong++; JE_playNewSong(); youStopped = false; break; default: break; } } } while (!quit); JE_updateColorsFast(black); //JE_fadeBlack(10); JE_setVol(255, fxVolume); }
void jukebox( void ) { bool trigger_quit = false, // true when user wants to quit quitting = false; bool hide_text = false; bool fade_looped_songs = true, fading_song = false; bool stopped = false; bool fx = false; int fx_num = 0; int palette_fade_steps = 15; int diff[256][3]; init_step_fade_palette(diff, vga_palette, 0, 255); JE_starlib_init(); int fade_volume = tyrMusicVolume; for (; ; ) { if (!stopped && !audio_disabled) { if (songlooped && fade_looped_songs) fading_song = true; if (fading_song) { if (fade_volume > 5) { fade_volume -= 2; } else { fade_volume = tyrMusicVolume; fading_song = false; } set_volume(fade_volume, fxVolume); } if (!playing || (songlooped && fade_looped_songs && !fading_song)) play_song(mt_rand() % MUSIC_NUM); } setdelay(1); SDL_FillRect(VGAScreenSeg, NULL, 0); // starlib input needs to be rewritten JE_starlib_main(); push_joysticks_as_keyboard(); service_SDL_events(true); if (!hide_text) { char buffer[60]; if (fx) snprintf(buffer, sizeof(buffer), "%d %s", fx_num + 1, soundTitle[fx_num]); else snprintf(buffer, sizeof(buffer), "%d %s", song_playing + 1, musicTitle[song_playing]); const int x = VGAScreen->w / 2; #ifdef ANDROID draw_font_hv(VGAScreen, x, 170, "Press the Back button to quit the jukebox.", small_font, centered, 1, 0); draw_font_hv(VGAScreen, x, 180, "Touch to change the song being played.", small_font, centered, 1, 0); #else draw_font_hv(VGAScreen, x, 170, "Press ESC to quit the jukebox.", small_font, centered, 1, 0); draw_font_hv(VGAScreen, x, 180, "Arrow keys change the song being played.", small_font, centered, 1, 0); #endif draw_font_hv(VGAScreen, x, 190, buffer, small_font, centered, 1, 4); } if (palette_fade_steps > 0) step_fade_palette(diff, palette_fade_steps--, 0, 255); JE_showVGA(); wait_delay(); #ifdef ANDROID if (mousedown) { wait_noinput(true, true, true); newkey = true; if (mouse_x < 160) lastkey_sym = SDLK_LEFT; else lastkey_sym = SDLK_RIGHT; } #else // quit on mouse click Uint16 x, y; if (JE_mousePosition(&x, &y) > 0) trigger_quit = true; #endif if (newkey) { switch (lastkey_sym) { case SDLK_ESCAPE: // quit jukebox case SDLK_q: trigger_quit = true; break; case SDLK_SPACE: hide_text = !hide_text; break; case SDLK_f: fading_song = !fading_song; break; case SDLK_n: fade_looped_songs = !fade_looped_songs; break; case SDLK_SLASH: // switch to sfx mode fx = !fx; break; case SDLK_COMMA: if (fx && --fx_num < 0) fx_num = SAMPLE_COUNT - 1; break; case SDLK_PERIOD: if (fx && ++fx_num >= SAMPLE_COUNT) fx_num = 0; break; case SDLK_SEMICOLON: if (fx) JE_playSampleNum(fx_num + 1); break; case SDLK_LEFT: case SDLK_UP: case SDLK_LCTRL: play_song((song_playing > 0 ? song_playing : MUSIC_NUM) - 1); stopped = false; break; case SDLK_RETURN: case SDLK_RIGHT: case SDLK_DOWN: case SDLK_LALT: play_song((song_playing + 1) % MUSIC_NUM); stopped = false; break; case SDLK_s: // stop song stop_song(); stopped = true; break; case SDLK_r: // restart song restart_song(); stopped = false; break; default: break; } } // user wants to quit, start fade-out if (trigger_quit && !quitting) { palette_fade_steps = 15; SDL_Color black = { 0, 0, 0 }; init_step_fade_solid(diff, black, 0, 255); quitting = true; } // if fade-out finished, we can finally quit if (quitting && palette_fade_steps == 0) break; } set_volume(tyrMusicVolume, fxVolume); }