Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * OpenTyrian: A modern cross-platform port of Tyrian
  3.  * Copyright (C) 2007-2009  The OpenTyrian Development Team
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  18.  */
  19. #include "scroller.h"
  20.  
  21. #include "font.h"
  22. #include "joystick.h"
  23. #include "jukebox.h"
  24. #include "keyboard.h"
  25. #include "loudness.h"
  26. #include "mtrand.h"
  27. #include "nortsong.h"
  28. #include "nortvars.h"
  29. #include "opentyr.h"
  30. #include "palette.h"
  31. #include "sprite.h"
  32. #include "varz.h"
  33. #include "vga256d.h"
  34. #include "video.h"
  35.  
  36. #include <string.h>
  37.  
  38. const struct about_text_type about_text[] =
  39. {
  40.         {0x30, "----- ~OpenTyrian~ -----"},
  41.         {0x00, ""},
  42.         {0x0b, "...eliminating Microsol,"},
  43.         {0x0b, "one planet at a time..."},
  44.         {0x00, ""},
  45.         {0x00, ""},
  46.         {0x30, "----- ~Developers~ -----"},
  47.         {0x00, ""},
  48.         {0x03, "Carl Reinke // Mindless"},
  49.         {0x07, "Yuri Schlesner // yuriks"},
  50.         {0x04, "Casey McCann // syntaxglitch"},
  51.         {0x00, ""},
  52.         {0x00, ""},
  53.         {0x30, "----- ~Thanks~ -----"},
  54.         {0x00, ""},
  55.         {0x0e, "Thanks to everyone who has"},
  56.         {0x0e, "assisted the developers by testing"},
  57.         {0x0e, "the game and reporting bugs."},
  58.         {0x00, ""},
  59.         {0x00, ""},
  60.         {0x05, "Thanks to ~DOSBox~ for the"},
  61.         {0x05, "FM-Synthesis emulator and"},
  62.         {0x05, "~AdPlug~ for the Loudness player."},
  63.         {0x00, ""},
  64.         {0x00, ""},
  65.         {0x32, "And special thanks to ~Jason Emery~"},
  66.         {0x32, "for making all this possible"},
  67.         {0x32, "by giving Tyrian to its fans."},
  68.         {0x00, ""},
  69.         {0x00, ""},
  70. /*      {0x00, "This is line color test ~0~."},
  71.         {0x01, "This is line color test ~1~."},
  72.         {0x02, "This is line color test ~2~."},
  73.         {0x03, "This is line color test ~3~."},
  74.         {0x04, "This is line color test ~4~."},
  75.         {0x05, "This is line color test ~5~."},
  76.         {0x06, "This is line color test ~6~."},
  77.         {0x07, "This is line color test ~7~."},
  78.         {0x08, "This is line color test ~8~."},
  79.         {0x09, "This is line color test ~9~."},
  80.         {0x0a, "This is line color test ~A~."},
  81.         {0x0b, "This is line color test ~B~."},
  82.         {0x0c, "This is line color test ~C~."},
  83.         {0x0d, "This is line color test ~D~."},
  84.         {0x0e, "This is line color test ~E~."},
  85.         {0x0f, "This is line color test ~F~."},*/
  86.         {0x00, ""},
  87.         {0x00, ""},
  88.         {0x00, ""},
  89.         {0x00, ""},
  90.         {0x00, ""},
  91.         {0x00, ""},
  92.         {0x00, "Press a key to leave."},
  93.         {0x00, NULL}
  94. };
  95.  
  96. #define LINE_HEIGHT 15
  97.  
  98. #define MAX_BEER 5
  99. #define BEER_SHAPE 241
  100.  
  101. struct coin_def_type {
  102.         int shape_num;
  103.         int frame_count;
  104.         bool reverse_anim;
  105. };
  106.  
  107. #define MAX_COINS 20
  108. struct coin_def_type coin_defs[] =
  109. {
  110.         {1, 6}, {7, 6}, {20, 6}, {26, 6}, // Coins
  111.         {14, 5, true}, {32, 5, true}, {51, 5, true} // Gems
  112. };
  113.  
  114. /* Text is an array of strings terminated by a NULL */
  115. void scroller_sine( const struct about_text_type text[] )
  116. {
  117.         bool ale = mt_rand() % 2;
  118.  
  119.         int visible_lines = vga_height / LINE_HEIGHT + 1;
  120.         int current_line = -visible_lines;
  121.         int y = 0;
  122.         bool fade_in = true;
  123.  
  124.         struct coin_type { int x, y, vel, type, cur_frame; bool backwards; } coins[MAX_COINS];
  125.         struct { int x, y, ay, vx, vy; } beer[MAX_BEER];
  126.  
  127.         if (ale)
  128.         {
  129.                 memset(beer, 0, sizeof(beer));
  130.         } else {
  131.                 for (int i = 0; i < MAX_COINS; i++)
  132.                 {
  133.                         coins[i].x = mt_rand() % (vga_width - 12);
  134.                         coins[i].y = mt_rand() % (vga_height - 20 - 14);
  135.  
  136.                         coins[i].vel = (mt_rand() % 4) + 1;
  137.                         coins[i].type = mt_rand() % COUNTOF(coin_defs);
  138.                         coins[i].cur_frame = mt_rand() % coin_defs[coins[i].type].frame_count;
  139.                         coins[i].backwards = false;
  140.                 }
  141.         }
  142.  
  143.         fade_black(10);
  144.  
  145.         wait_noinput(true, true, true);
  146.  
  147.         play_song(40); // BEER
  148.  
  149.         while (!JE_anyButton())
  150.         {
  151.                 setdelay(3);
  152.  
  153.                 JE_clr256(VGAScreen);
  154.  
  155.                 if (!ale)
  156.                 {
  157.                         for (int i = 0; i < MAX_COINS/2; i++)
  158.                         {
  159.                                 struct coin_type *coin = &coins[i];
  160.                                 blit_sprite2(VGAScreen, coin->x, coin->y, eShapes[4], coin_defs[coin->type].shape_num + coin->cur_frame);
  161.                         }
  162.                 }
  163.  
  164.                 for (int i = 0; i < visible_lines; i++)
  165.                 {
  166.                         if (current_line + i >= 0)
  167.                         {
  168.                                 if (text[current_line + i].text == NULL)
  169.                                 {
  170.                                         break;
  171.                                 }
  172.  
  173.                                 int line_x = VGAScreen->w / 2;
  174.                                 int line_y = i * LINE_HEIGHT - y;
  175.  
  176.                                 // smooths edges on sine-wave text
  177.                                 if (text[i + current_line].effect & 0x20)
  178.                                 {
  179.                                         draw_font_hv(VGAScreen, line_x + 1, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -10);
  180.                                         draw_font_hv(VGAScreen, line_x - 1, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -10);
  181.                                 }
  182.  
  183.                                 draw_font_hv(VGAScreen, line_x, line_y, text[i + current_line].text, normal_font, centered, text[i + current_line].effect & 0x0f, -4);
  184.  
  185.                                 if (text[i + current_line].effect & 0x10)
  186.                                 {
  187.                                         for (int j = 0; j < LINE_HEIGHT; j++)
  188.                                         {
  189.                                                 if (line_y + j >= 10 && line_y + j <= vga_height - 10)
  190.                                                 {
  191.                                                         int waver = sinf((((line_y + j) / 2) % 10) / 5.0f * M_PI) * 3;
  192.                                                         memmove(&((Uint8 *)VGAScreen->pixels)[VGAScreen->pitch * (line_y + j) + waver],
  193.                                                                         &((Uint8 *)VGAScreen->pixels)[VGAScreen->pitch * (line_y + j)],
  194.                                                                         VGAScreen->pitch);
  195.                                                 }
  196.                                         }
  197.                                 }
  198.                         }
  199.                 }
  200.  
  201.                 if (++y == LINE_HEIGHT)
  202.                 {
  203.                         y = 0;
  204.  
  205.                         if (current_line < 0 || text[current_line].text != NULL)
  206.                                 ++current_line;
  207.                         else
  208.                                 current_line = -visible_lines;
  209.                 }
  210.  
  211.                 if (!ale)
  212.                 {
  213.                         for (int i = MAX_COINS/2; i < MAX_COINS; i++)
  214.                         {
  215.                                 struct coin_type *coin = &coins[i];
  216.                                 blit_sprite2(VGAScreen, coin->x, coin->y, eShapes[4], coin_defs[coin->type].shape_num + coin->cur_frame);
  217.                         }
  218.                 }
  219.  
  220.                 fill_rectangle_xy(VGAScreen, 0, 0, vga_width - 1, 14, 0);
  221.                 fill_rectangle_xy(VGAScreen, 0, vga_height - 14, vga_width - 1, vga_height - 1, 0);
  222.  
  223.                 if (!ale)
  224.                 {
  225.                         for (int i = 0; i < MAX_COINS; i++)
  226.                         {
  227.                                 struct coin_type *coin = &coins[i];
  228.  
  229.                                 if (coin->backwards)
  230.                                 {
  231.                                         coin->cur_frame--;
  232.                                 } else {
  233.                                         coin->cur_frame++;
  234.                                 }
  235.                                 if (coin->cur_frame == coin_defs[coin->type].frame_count)
  236.                                 {
  237.                                         if (coin_defs[coin->type].reverse_anim)
  238.                                         {
  239.                                                 coin->backwards = true;
  240.                                                 coin->cur_frame -= 2;
  241.                                         } else {
  242.                                                 coin->cur_frame = 0;
  243.                                         }
  244.                                 }
  245.                                 if (coin->cur_frame == -1)
  246.                                 {
  247.                                         coin->cur_frame = 1;
  248.                                         coin->backwards = false;
  249.                                 }
  250.  
  251.                                 coin->y += coin->vel;
  252.                                 if (coin->y > vga_height - 14)
  253.                                 {
  254.                                         coin->x = mt_rand() % (vga_width - 12);
  255.                                         coin->y = 0;
  256.  
  257.                                         coin->vel = (mt_rand() % 4) + 1;
  258.                                         coin->type = mt_rand() % COUNTOF(coin_defs);
  259.                                         coin->cur_frame = mt_rand() % coin_defs[coin->type].frame_count;
  260.                                 }
  261.                         }
  262.                 } else {
  263.                         for (uint i = 0; i < COUNTOF(beer); i++)
  264.                         {
  265.                                 while (beer[i].vx == 0)
  266.                                 {
  267.                                         beer[i].x = mt_rand() % (vga_width - 24);
  268.                                         beer[i].y = mt_rand() % (vga_height - 28 - 50);
  269.  
  270.                                         beer[i].vx = (mt_rand() % 5) - 2;
  271.                                 }
  272.  
  273.                                 beer[i].vy++;
  274.  
  275.                                 if (beer[i].x + beer[i].vx > vga_width - 24 || beer[i].x + beer[i].vx < 0) // check if the beer hit the sides
  276.                                 {
  277.                                         beer[i].vx = -beer[i].vx;
  278.                                 }
  279.                                 beer[i].x += beer[i].vx;
  280.  
  281.                                 if (beer[i].y + beer[i].vy > vga_height - 28) // check if the beer hit the bottom
  282.                                 {
  283.                                         if ((beer[i].vy) < 8) // make sure the beer bounces!
  284.                                         {
  285.                                                 beer[i].vy += mt_rand() % 2;
  286.                                         } else if (beer[i].vy > 16) { // make sure the beer doesn't bounce too high
  287.                                                 beer[i].vy = 16;
  288.                                         }
  289.                                         beer[i].vy = -beer[i].vy + (mt_rand() % 3 - 1);
  290.  
  291.                                         beer[i].x += (beer[i].vx > 0 ? 1 : -1) * (i % 2 ? 1 : -1);
  292.                                 }
  293.                                 beer[i].y += beer[i].vy;
  294.  
  295.                                 blit_sprite2x2(VGAScreen, beer[i].x, beer[i].y, eShapes[4], BEER_SHAPE);
  296.                         }
  297.                 }
  298.  
  299.                 JE_showVGA();
  300.  
  301.                 if (fade_in)
  302.                 {
  303.                         fade_in = false;
  304.                         fade_palette(colors, 10, 0, 255);
  305.  
  306.                         SDL_Color white = { 255, 255, 255 };
  307.                         set_colors(white, 254, 254);
  308.                 }
  309.  
  310.                 wait_delay();
  311.         }
  312.  
  313.         fade_black(10);
  314. }
  315.  
  316.