Commit 3386f728 authored by Markus Koschany's avatar Markus Koschany

Imported Upstream version 0.8.2

parents
This diff is collapsed.
# Makefile for TuxPuck , Copyright Jacob Kroon 2001-2002
NAME = tuxpuck
VERSION = 0.8.2
CC = gcc
CFLAGS += -D_VERSION=\"$(VERSION)\" -g -Wall
CSOURCES = tuxpuck.c video.c audio.c menu.c sprite.c font.c timer.c \
board.c entity.c glass.c scoreboard.c player.c zoom.c png.c \
jpg.c intro.c tux.c arcana.c
INCLUDES = tuxpuck.h video.h audio.h font.h
#############################################################
OBJS=$(CSOURCES:.c=.o)
ifdef COMSPEC
OBJS += w32icon.o
endif
%.o : %.c
$(CC) $(CFLAGS) `sdl-config --cflags` -c -o $@ $<
$(NAME) : $(OBJS)
cd data; $(MAKE)
$(CC) $(CFLAGS) $(OBJS) data/libdata.a `sdl-config --libs` -lm -lpng \
-ljpeg -lz -lvorbisfile -lvorbis -logg -o $(NAME)
w32icon.o : data/icons/tuxpuck.ico
echo AppIcon ICON "data/icons/tuxpuck.ico" > temp.rc
windres -i temp.rc -o w32icon.o
rm temp.rc
clean :
cd utils; $(MAKE) clean;
cd data; $(MAKE) clean;
rm -f *~ $(OBJS) $(NAME)
indent :
cd utils; $(MAKE) indent;
indent -br -brs -sob -ce -c50 -npsl -npcs $(CSOURCES) $(INCLUDES)
rm -f *~
dist :
$(MAKE) clean
mkdir $(NAME)-$(VERSION)
cp $(CSOURCES) $(INCLUDES) readme.txt todo.txt bugs.txt thanks.txt \
COPYING Makefile $(NAME)-$(VERSION)
cp -R man utils data $(NAME)-$(VERSION)
tar -cf $(NAME)-$(VERSION).tar $(NAME)-$(VERSION)
tar -f $(NAME)-$(VERSION).tar --delete \
`tar -tf $(NAME)-*.tar | grep -w -e ".svn/"`
gzip -9 $(NAME)-$(VERSION).tar
rm -Rf $(NAME)-$(VERSION)
install : $(NAME)
install -d $(DESTDIR)/usr/bin
install -d $(DESTDIR)/usr/man/man6
install -m755 $(NAME) $(DESTDIR)/usr/bin
install -m644 man/$(NAME).6.gz $(DESTDIR)/usr/man/man6
/* arcana.c - Copyright (C) 2001-2002 Jacob Kroon, see COPYING for details */
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "video.h"
#include "tuxpuck.h"
/* defines */
#define SERVE_STATE_FLOAT_FORWARD 1
#define SERVE_STATE_SWIRL 2
#define SERVE_STATE_RELEASE 3
#define SWIRL_RADIUS ((float)10.0)
#define FLOAT_SPEED ((float)0.01)
#define COUNTER_ACC ((float)0.01)
#define RELEASE_SPEED ((float)0.5)
/* externals */
extern unsigned char arcana_png[];
/* statics */
static char _name[] = "Arcana";
static Uint8 _serve_state = 0, _is_ready = 1;
/* functions */
static void _arcana_free(AIPlayer * player)
{
SDL_FreeSurface(player->sdl_image);
free(player);
}
static Uint8 _arcana_reblit(AIPlayer * player, Uint32 time)
{
switch (player->state) {
case PLAYER_STATE_WIN_POINT:
case PLAYER_STATE_LOOSE_POINT:
_is_ready = 1;
break;
case PLAYER_STATE_WIN_GAME:
case PLAYER_STATE_LOOSE_GAME:
return 0;
default:
break;
}
return 1;
}
static Uint8 _ready(void)
{
return _is_ready;
}
static void _arcana_serve(AIPlayer * player, Uint32 time)
{
static float counter, counter_speed, angle_limit;
static Uint8 corner = 0;
entity_move_towards(player->pad, 0, 35, 0.005, time);
switch (_serve_state) {
case SERVE_STATE_FLOAT_FORWARD:
if (entity_move_towards
((Entity *) player->puck, 0, 10 - SWIRL_RADIUS, FLOAT_SPEED,
time) == 0) {
_serve_state = SERVE_STATE_SWIRL;
counter = -M_PI_2;
counter_speed = 0.005;
corner = (Uint8) ((float) rand() / RAND_MAX * 2);
if (corner == 1)
angle_limit = 2 * M_PI * 5 + M_PI + M_PI_2 / 2;
else
angle_limit = 2 * M_PI * 5 + M_PI;
}
break;
case SERVE_STATE_SWIRL:
counter_speed += time * COUNTER_ACC / 1000.0;
counter += counter_speed * time;
entity_set_position((Entity *) player->puck,
SWIRL_RADIUS * cos(counter),
10 + SWIRL_RADIUS * sin(counter));
if (counter > angle_limit) {
_serve_state = SERVE_STATE_RELEASE;
entity_set_position((Entity *) player->puck,
SWIRL_RADIUS * cos(angle_limit),
10 + SWIRL_RADIUS * sin(angle_limit));
}
break;
case SERVE_STATE_RELEASE:
if (corner == 1)
entity_set_velocity((Entity *) player->puck,
RELEASE_SPEED * 0.477, RELEASE_SPEED * -0.879);
else
entity_set_velocity((Entity *) player->puck,
RELEASE_SPEED * -0.140, RELEASE_SPEED * -0.990);
player->set_state(player, PLAYER_STATE_IDLE);
break;
default:
break;
}
}
static void _arcana_set_state(AIPlayer * player, Uint8 state)
{
player->state = state;
switch (state) {
case PLAYER_STATE_SERVE:
if ((float) rand() / RAND_MAX > 0.50) {
_serve_state = SERVE_STATE_FLOAT_FORWARD;
player->strategy.serve = _arcana_serve;
} else
player->strategy.serve = dumb_serve;
break;
default:
break;
}
}
AIPlayer *arcana_create(Pad * pad, Puck * puck)
{
AIPlayer *player = NULL;
player = malloc(sizeof(AIPlayer));
memset(player, 0, sizeof(AIPlayer));
player->sdl_image = video_create_png_surface(arcana_png, NULL);
SDL_SetColorKey(player->sdl_image, SDL_SRCCOLORKEY, 177);
player->rect.x = SCREEN_W / 2 - player->sdl_image->w / 2;
player->rect.y = BOARD_TOP - player->sdl_image->h;
player->rect.w = player->rect.h = 0;
player->name = _name;
player->pad = pad;
player->puck = puck;
player->speed = 2.5;
player->hit_power = 2.5;
player->state = PLAYER_STATE_IDLE;
player->reblit = _arcana_reblit;
player->set_state = _arcana_set_state;
player->ready = _ready;
player->free = _arcana_free;
player->strategy.idle = dumb_idle;
player->strategy.serve = dumb_serve;
player->strategy.backup = smart_backup;
player->strategy.aim = dumb_aim;
player->strategy.hit = dumb_hit;
return player;
}
/* audio.c - Copyright (C) 2001-2002 Jacob Kroon, see COPYING for details */
#include <stdlib.h>
#include <string.h>
#include <SDL_audio.h>
#include <SDL_endian.h>
#include <vorbis/vorbisfile.h>
#include "audio.h"
/* defines */
#define BUFFER_SIZE ((Uint32)128)
#define BUFFER_LIMIT ((Uint32)1000000000)
/* structs */
struct _Sound {
Uint32 length;
Uint8 *buffer;
Uint8 single;
};
typedef struct _SoundNode {
Uint32 position;
Sound *sound;
struct _SoundNode *next;
} SoundNode;
/* statics */
static Uint8 _mute = 0, _initiated = 0;
static SDL_AudioSpec _spec;
static SoundNode *_sound_node = NULL;
/* functions */
static size_t _RWops_ogg_read(void *ptr, size_t size, size_t nmemb,
void *source)
{
return ((size_t) SDL_RWread((SDL_RWops *) source, ptr, size, nmemb));
}
static int _RWops_ogg_seek(void *source, ogg_int64_t offset, int whence)
{
return (SDL_RWseek((SDL_RWops *) source, offset, whence));
}
static int _RWops_ogg_close(void *source)
{
return 0;
}
static long _RWops_ogg_tell(void *source)
{
return ((long) SDL_RWtell((SDL_RWops *) source));
}
static const ov_callbacks _ogg_callbacks = {
_RWops_ogg_read,
_RWops_ogg_seek,
_RWops_ogg_close,
_RWops_ogg_tell
};
static void _audio_mix_audio(void *unused, Uint8 * stream, int length)
{
SoundNode *node = NULL, *prev = NULL, *temp = NULL;
int toWrite = 0;
if (_mute)
return;
prev = NULL;
node = _sound_node;
while (node != NULL) {
if (node->position + length > node->sound->length)
toWrite = node->sound->length - node->position;
else
toWrite = length;
SDL_MixAudio(stream, &node->sound->buffer[node->position], toWrite,
SDL_MIX_MAXVOLUME);
node->position += toWrite;
if (toWrite < length) {
if (prev)
prev->next = node->next;
else
_sound_node = node->next;
temp = node->next;
free(node);
node = temp;
} else {
prev = node;
node = node->next;
}
}
}
void audio_init(void)
{
SDL_AudioSpec fmt;
fmt.freq = 11025;
fmt.format = AUDIO_S16SYS;
fmt.channels = 1;
fmt.samples = BUFFER_SIZE;
fmt.callback = _audio_mix_audio;
fmt.userdata = NULL;
if (SDL_OpenAudio(&fmt, &_spec) < 0)
_initiated = 0;
else {
SDL_PauseAudio(0);
_initiated = 1;
}
}
void audio_deinit(void)
{
SoundNode *node = _sound_node, *next = NULL;
while (node) {
next = node->next;
free(node);
node = next;
}
if (_initiated)
SDL_CloseAudio();
}
void audio_set_mute(Uint8 mute)
{
_mute = mute;
}
void audio_play_sound(Sound * sound)
{
SoundNode *node = NULL;
if (!sound || !_initiated || _mute)
return;
if (sound->single) {
node = _sound_node;
while (node != NULL) {
if (node->sound == sound)
return;
node = node->next;
}
}
node = (SoundNode *) malloc(sizeof(SoundNode));
node->sound = sound;
node->position = 0;
node->next = NULL;
if (_sound_node != NULL)
node->next = _sound_node;
_sound_node = node;
}
Sound *audio_create_sound(Uint8 * data, Uint32 * memcounter)
{
OggVorbis_File *vf = NULL;
vorbis_info *vi = NULL;
SDL_RWops *src = NULL;
Sound *sound = NULL;
int dummy = 0;
Uint8 ov_open_success = 0;
Uint32 size = 0, buffer_size = 0, bytes_read = 0, counter = 0;
memcpy(&size, data, sizeof(Uint32));
if (memcounter)
*memcounter += size + sizeof(Uint32);
if (!_initiated)
goto done;
data += sizeof(Uint32);
src = SDL_RWFromMem(data, size);
vf = (OggVorbis_File *) malloc(sizeof(OggVorbis_File));
if (ov_open_callbacks(src, vf, NULL, 0, _ogg_callbacks) != 0)
goto done;
ov_open_success = 1;
vi = ov_info(vf, -1);
if (vi->channels != _spec.channels || vi->rate != _spec.freq)
goto done;
buffer_size = ov_pcm_total(vf, -1) * _spec.channels * 2;
if (buffer_size > BUFFER_LIMIT)
goto done;
sound = (Sound *) malloc(sizeof(Sound));
sound->length = buffer_size;
sound->single = 1;
/* ATTENTION!!!!! UGLY HACK
* I've added +4096 bytes to be mallocated, but I have no
* idea _why_ this prevents TuxPuck from crashing :)
*/
sound->buffer = (Uint8 *) malloc(buffer_size + 4096);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
while ((bytes_read =
ov_read(vf, (char *) &sound->buffer[counter], 4096, 1, 2, 1,
&dummy)) != 0) {
counter += bytes_read;
if (counter > buffer_size)
goto done;
}
#else
while ((bytes_read =
ov_read(vf, (char *) &sound->buffer[counter], 4096, 0, 2, 1,
&dummy)) != 0) {
counter += bytes_read;
if (counter > buffer_size)
goto done;
}
#endif
done:
if (ov_open_success)
ov_clear(vf);
if (src)
SDL_FreeRW(src);
if (vf)
free(vf);
return sound;
}
void audio_set_single(Sound * sound, Uint8 single)
{
sound->single = single;
}
void audio_free_sound(Sound * sound)
{
SoundNode *node = NULL, *prev = NULL, *temp = NULL;
if (sound) {
prev = NULL;
node = _sound_node;
while (node) {
if (node->sound == sound) {
if (prev)
prev->next = node->next;
else
_sound_node = node->next;
temp = node->next;
free(node);
node = temp;
} else {
prev = node;
node = node->next;
}
}
SDL_FreeWAV(sound->buffer);
free(sound);
}
}
/* audio.h - Copyright (C) 2001-2002 Jacob Kroon, see COPYING for details */
#ifndef _AUDIO_H
#define _AUDIO_H
/* includes */
#include <SDL_types.h>
/* structs */
typedef struct _Sound Sound;
/* functions */
void audio_init(void);
void audio_deinit(void);
Sound *audio_create_sound(Uint8 *, Uint32 *);
void audio_free_sound(Sound *);
void audio_play_sound(Sound *);
void audio_set_mute(Uint8);
void audio_set_single(Sound *, Uint8);
#endif /* _AUDIO_H */
/* board.c - Copyright (C) 2001-2002 Jacob Kroon, see COPYING for details */
#include "video.h"
#include "tuxpuck.h"
/* externals */
extern unsigned char board_jpg[];
/* statics */
static SDL_Surface *_sdl_board;
static Uint8 _state = 0, _turn = 0;
static float _coeff[4];
static Pad *_pad_1, *_pad_2;
static Puck *_puck;
static SDL_Rect _rect = { 0, 0, 0, 0 };
/* functions */
static Uint8 _get_scorer(void)
{
float puck_z;
if (puck_is_dead(_puck))
return 0;
entity_get_position((Entity *) _puck, NULL, &puck_z);
if (puck_z > 40)
return 1;
else if (puck_z < -40)
return 2;
return 0;
}
void board_init(void)
{
_state = BOARD_STATE_NEW_PUCK;
_sdl_board = video_create_jpg_surface(board_jpg, NULL);
_rect.x = SCREEN_W / 2 - _sdl_board->w / 2;
_rect.y = SCREEN_H - _sdl_board->h;
_rect.w = _rect.h = 0;
_pad_1 = pad_create(1);
_pad_2 = pad_create(2);
_puck = puck_create();
_turn = 1;
glass_init();
_coeff[0] = 80 * (BOARD_BOTTOM * BOARD_TOP) / (BOARD_BOTTOM - BOARD_TOP);
_coeff[1] = 40 * (BOARD_BOTTOM + BOARD_TOP) / (BOARD_BOTTOM - BOARD_TOP);
_coeff[2] =
80 * (1.0 * BOARD_LEFT / BOARD_RIGHT) / (1.0 - BOARD_LEFT / BOARD_RIGHT);
_coeff[3] =
40 * (1.0 + BOARD_LEFT / BOARD_RIGHT) / (1.0 - BOARD_LEFT / BOARD_RIGHT);
video_fade(_sdl_board, 1000);
}
void board_deinit(void)
{
SDL_FreeSurface(_sdl_board);
pad_free(_pad_1);
pad_free(_pad_2);
puck_free(_puck);
glass_deinit();
}
Pad *board_get_pad(Uint8 who)
{
if (who == 1)
return _pad_1;
else if (who == 2)
return _pad_2;
else
return NULL;
}
Puck *board_get_puck(void)
{
return _puck;
}
void board_blit(void)
{
video_blit(_sdl_board, NULL, &_rect);
}
Uint8 board_update(Uint32 time)
{
Uint8 scorer;
float puck_x, puck_z;
switch (_state) {
case BOARD_STATE_PLAY:
if (puck_will_get_hit_by(_puck, _pad_1, time))
puck_get_hit_by(_puck, _pad_1, time);
else if (puck_will_get_hit_by(_puck, _pad_2, time))
puck_get_hit_by(_puck, _pad_2, time);
puck_move(_puck, time);
break;
case BOARD_STATE_CRASH_GLASS:
if (glass_update(time) == 0) {
glass_erase();
_state = BOARD_STATE_NEW_PUCK;
if (_turn == 1)
_turn = 2;
else
_turn = 1;
}
break;
case BOARD_STATE_NEW_PUCK:
if (_turn == 1) {
if (entity_move_towards((Entity *) _puck, 0, -21, 0.05, time) == 0) {
_state = BOARD_STATE_PLAY;
entity_set_velocity((Entity *) _puck, 0, 0);
puck_set_state(_puck, PUCK_STATE_ALIVE);
}
} else {
if (entity_move_towards((Entity *) _puck, 0, 21, 0.05, time) == 0) {
_state = BOARD_STATE_PLAY;
entity_set_velocity((Entity *) _puck, 0, 0);
puck_set_state(_puck, PUCK_STATE_ALIVE);
}
}
break;
default:
break;
}
if ((scorer = _get_scorer()) != 0) {
_state = BOARD_STATE_CRASH_GLASS;
entity_get_position((Entity *) _puck, &puck_x, &puck_z);
glass_smash(puck_x, puck_z);
puck_set_state(_puck, PUCK_STATE_DEAD);
}
entity_move(_pad_1, time);
entity_move(_pad_2, time);
return scorer;
}
void board_clean_up(void)
{
entity_erase(_pad_1);
entity_erase(_pad_2);
entity_erase((Entity *) _puck);
if (_state == BOARD_STATE_CRASH_GLASS)
glass_erase();
}
void board_reblit(void)
{
float p1, p2, p, g = 0;
entity_get_position(_pad_1, NULL, &p1);
entity_get_position(_pad_2, NULL, &p2);
entity_get_position((Entity *) _puck, NULL, &p);
if (_state == BOARD_STATE_CRASH_GLASS) {
glass_get_position(NULL, &g);
if (g > 0)
glass_blit();
}
if (p < p1) {
entity_blit(_pad_2);
entity_blit(_pad_1);
entity_blit((Entity *) _puck);
} else if (p < p2) {
entity_blit(_pad_2);
entity_blit((Entity *) _puck);
entity_blit(_pad_1);
} else {
entity_blit((Entity *) _puck);
entity_blit(_pad_2);
entity_blit(_pad_1);
}
if (_state == BOARD_STATE_CRASH_GLASS) {
if (g < 0)
glass_blit();
}
}
Uint8 board_get_state(void)
{
return _state;
}
Uint8 board_get_turn(void)
{
return _turn;
}
float board_calc_y(float y)
{
return (_coeff[0] / (_coeff[1] + y));
}
float board_calc_scale(float y)
{
return _coeff[2] / (_coeff[3] + y);
}
BUGS
====
None?
# Makefile for TuxPuck , Copyright Jacob Kroon 2001-2002
CC = gcc
SOURCES = pad_png.c puck_png.c tux_png.c glass_png.c scoreboard_png.c \
arcana_png.c mousebar_png.c title_jpg.c board_jpg.c \
logo_jpg.c crash_ogg.c nock_ogg.c tux_apps_ogg.c \
tux_boos_ogg.c tux_eyes_spr.c monos_fnt.c monob_fnt.c
#############################################################
OBJS=$(SOURCES:.c=.o)
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
libdata.a : $(OBJS)
ar r libdata.a $(OBJS)
ranlib libdata.a
$(SOURCES):
cd ../utils/; $(MAKE)
../utils/ttf2font ttfs/mono.ttf monos.fnt 30 30
../utils/data2c monos.fnt monos_fnt
../utils/ttf2font ttfs/mono.ttf monob.fnt 45 45
../utils/data2c monob.fnt monob_fnt
rm *.fnt
../utils/data2c jpgs/title.jpg title_jpg
../utils/data2c jpgs/board.jpg board_jpg
../utils/data2c jpgs/logo.jpg logo_jpg
../utils/data2c pngs/pad.png pad_png
../utils/data2c pngs/puck.png puck_png
../utils/data2c pngs/scoreboard.png scoreboard_png
../utils/data2c pngs/mousebar.png mousebar_png
../utils/data2c pngs/glass.png glass_png
../utils/data2c pngs/piece1.png piece1_png
../utils/data2c pngs/piece2.png piece2_png
../utils/data2c pngs/piece3.png piece3_png
../utils/data2c pngs/piece4.png piece4_png
../utils/data2c pngs/piece5.png piece5_png
mv glass_png.c temp; cat temp piece?_png.c > glass_png.c
rm piece?_png.c temp
../utils/data2c sounds/crash.ogg crash_ogg
../utils/data2c sounds/nock.ogg nock_ogg
# Tux
../utils/anim tux/eyes.ac tux_eyes.spr
../utils/data2c tux_eyes.spr tux_eyes_spr
rm tux_eyes.spr
../utils/data2c tux/tux.png tux_png
../utils/data2c tux/apps.ogg tux_apps_ogg
../utils/data2c tux/boos.ogg tux_boos_ogg
# Arcana
../utils/data2c arcana/arcana.png arcana_png
clean :
rm -f *~ $(SOURCES) $(OBJS) libdata.a
rm -rf pngs/.xvpics jpgs/.xvpics