[AD] New example program

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> Now for suggestion.  I've got an idea about attracting more attention
> to the AUTHORS file (and showing names in big letters :).  The idea is
> to make new example program which will read the AUTHORS file and will
> show it in various views: scrolling on the bottom line, scrolling up,
> fading in by pages, flying away, like titles in star wars, etc.

Here is a framework with one effect.  Perhaps, it was not such a good
idea, the file is already ~7 Kb in size.  The sample effect is
incomplete, it will run with different speed on different computers.

Compile with:

bash% gcc -O2 -o excredit excredit.c -lalleg

/*
 * excredit.c --- Mega credits
 *
 * This file is gift-ware.  This file is given to you freely
 * as a gift.  You may use, modify, redistribute, and generally hack
 * it about in any way you like, and you do not have to give anyone
 * anything in return.
 *
 * I do not accept any responsibility for any effects, adverse or
 * otherwise, that this code may have on just about anything that
 * you can think of.  Use it at your own risk.
 *
 * Copyright (C) 1999  Michael Bukin
 */


#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "allegro.h"


struct AUTHORS
{
   int lines_num;
   char **line;
   void **list;
};



/* Free memory allocated for authors.  */
void free_authors(struct AUTHORS *authors)
{
   void *next;
   void **node;

   if (authors) {
      if (authors->line)
	 free(authors->line);
      for (node = authors->list; node != 0; node = next) {
	 next = *node;
	 free(node);
      }
      free(authors);
   }
}



/* Try to read file into authors structure.  */
struct AUTHORS *read_credits_file(char *name)
{
   int line;
   void **node;
   FILE *file;
   char buf[256];
   char tmp[256];
   struct AUTHORS *authors;

   /* Create structure for storing strings.  */
   authors = malloc(sizeof(struct AUTHORS));
   if (authors == 0)
      return 0;
   authors->lines_num = 0;
   authors->line = 0;
   authors->list = 0;

   /* Try to open file.  */
   file = fopen(name, "rt");
   if (file == 0) {
      free(authors);
      return 0;
   }

   /* Read lines from file and store them.  */
   for (line = 0; fgets(buf, sizeof(buf), file) != 0; line++) {
      char *ptr;

      /* Strip trailing white spaces.  */
      for (ptr = buf + strlen(buf) - 1; ptr >= buf; ptr--)
	 if (!isspace (*ptr))
	    break;
      *(ptr + 1) = '\0';

      /* Convert string to Unicode.  */
      ptr = uconvert_toascii(buf, tmp);

      /* Allocate memory for string.  */
      node = malloc(sizeof(void*) + strlen(ptr) + 1);
      if (node == 0) {
	 free_authors(authors);
	 fclose(file);
	 return 0;
      }

      /* Add string to the list.  */
      *node = authors->list;
      strcpy((char*) (node + 1), ptr);
      authors->list = node;
   }

   /* Test for errors.  */
   if (ferror (file)) {
      free_authors(authors);
      fclose(file);
      return 0;
   }

   /* Try to close file.  */
   if (fclose(file)) {
      free_authors(authors);
      return 0;
   }

   /* Create array for string pointers.  */
   authors->lines_num = line;
   authors->line = malloc(line * sizeof(char*));
   if (authors->line == 0) {
      free_authors(authors);
      return 0;
   }

   /* Add strings to the array.  */
   for (line = authors->lines_num - 1, node = authors->list; node != 0; line--, node = *node)
      authors->line[line] = (char*) (node + 1);

   return authors;
}



/* Return next line index in the list of strings.  */
int next_authors_line(struct AUTHORS *authors, int line)
{
   return (((line + 1) >= authors->lines_num) ? 0 : (line + 1));
}



/* Read the AUTHORS file, trying several locations.  */
struct AUTHORS *read_authors(char *prog)
{
   struct AUTHORS *authors;
   char buf[256];

   replace_filename(buf, prog, "../AUTHORS", sizeof(buf));
   authors = read_credits_file(buf);
   if (authors == 0) {
      replace_filename(buf, prog, "AUTHORS", sizeof(buf));
      authors = read_credits_file(buf);
      if (authors == 0) {
	 authors = read_credits_file("../AUTHORS");
	 if (authors == 0) {
	    authors = read_credits_file("AUTHORS");
	 }
      }
   }

   return authors;
}



/* Available effects.  */
int effect_scroll_up(struct AUTHORS *authors, int *first_line);


/*
 * On entry:
 *  authors struct contains list of strings in the file.
 *  first_line contains line number which might be viewed first.
 */
typedef int (*EFFECT_FUNCTION)(struct AUTHORS *authors, int *first_line);
EFFECT_FUNCTION effects[] =
{
   effect_scroll_up,
   0
};



/* Timer interrupt (for timing events).  */
volatile unsigned int ticks = 0;

void timer(void)
{
   ticks++;
}

END_OF_FUNCTION(timer);



/* That's our main function.  */
int main(int argc, char *argv[])
{
   int mode, first_line;
   struct AUTHORS *authors;

   /* Initialize Allegro library, keyboard, mouse, timers and graphics mode.  */
   allegro_init();
   install_keyboard();
   install_mouse();
   install_timer();
   set_gfx_mode(GFX_SAFE, 640, 480, 0, 0);

   /* Install timer interrupt (0.2 seconds between ticks).  */
   LOCK_FUNCTION(timer);
   LOCK_VARIABLE(ticks);
   install_int(timer, 200);

   /* Read AUTHORS file.  */
   authors = read_authors(argv[0]);
   if (authors == 0) {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Error loading AUTHORS file!\n");
      return 1;
   }

   /* Cycle through effects.  */
   mode = 0;
   first_line = 0;
   while (1) {
      /* Cleanup after previous effect.  */
      drawing_mode(DRAW_MODE_SOLID, 0, 0, 0);
      text_mode(-1);
      fade_out(4);
      clear(screen);

      /* Exit by ESC.  */
      if ((*(effects[mode]))(authors, &first_line) == KEY_ESC) {
	 break;
      }

      /* Switch to next effect.  */
      if (effects[++mode] == 0)
	 mode = 0;
   }

   /* Free some memory.  */
   free_authors(authors);

   return 0;
}

END_OF_MAIN();



/* Everything scrolls up.  */
int effect_scroll_up(struct AUTHORS *authors, int *first_line)
{
   int sy, dy, h;
   int next_line;
   int backcolor;
   int textcolor;
   BITMAP *bmp;

   /* Create bitmap.  */
   h = text_height(font);
   bmp = create_bitmap(SCREEN_W, (SCREEN_H / h + 3) * h);
   if (bmp == 0) {
      /* Don't loop endlessly when something fails.  */
      return KEY_ESC;
   }

   /* Prepare palette.  */
   backcolor = 0;
   textcolor = 15;
   clear_to_color(screen, backcolor);
   set_palette(default_palette);

   /* Fill bitmap with one page of text.  */
   clear_to_color(bmp, backcolor);
   for (next_line = *first_line, dy = 0; dy < bmp->h; dy += h) {
      textout(bmp, font, authors->line[next_line], 0, dy, textcolor);
      next_line = next_authors_line(authors, next_line);
   }

   sy = 0;
   dy = SCREEN_H;
   while (!keypressed()) {
      /* Move text one line up.  */
      dy--;

      if (dy <= -h) {
	 /* Remove old line and add new line.  */
	 rectfill(bmp, 0, sy, bmp->w - 1, sy + h - 1, backcolor);
	 textout(bmp, font, authors->line[next_line], 0, sy, textcolor);

	 next_line = next_authors_line(authors, next_line);
	 *first_line = next_authors_line(authors, *first_line);

	 dy += h;
	 sy = (sy + h) % bmp->h;
      }

      /* Update screen.  */
      acquire_screen();
      blit(bmp, screen, 0, sy, 0, dy, SCREEN_W, bmp->h - sy);
      blit(bmp, screen, 0, 0, 0, dy + bmp->h - sy, SCREEN_W, sy);
      release_screen();
   }

   /* Clean up everything.  */
   destroy_bitmap(bmp);

   return (readkey() >> 8);
}

/*
 * excredit.c ends here
 */

-- 
Michael Bukin



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/