[ 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