/*
* Copyright (C) 2021 P. J. McDermott
*
* This file is part of Dodge Balls
*
* Dodge Balls is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dodge Balls is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dodge Balls. If not, see .
*/
#include
#include
#include
#include "collision.h"
#include "help.h"
#include "main.h"
#include "output.h"
#include "util.h"
const char *_db_help_text =
PACKAGE_NAME " version " PACKAGE_VERSION "\n"
"\n"
"Press Esc or Enter to exit help\n"
"\n"
"Evade the balls and get to the target! Dodge Balls is a simple "
"puzzle game with obstacle courses consisting of moving balls.\n"
"\n"
"The classic game is a liberated remake of a 2007 game, Dodgeball "
"v3.0, by the same author. It features 10 levels, each harder than "
"the last.\n"
"\n"
"How to Play\n"
"\n"
"Move your character (a smiley face in the classic game) through the "
"obstacle course to reach the target (a star in the classic game). If "
"you are hit by a ball, the level is restarted.\n"
"\n"
"Controls\n"
"\n"
"Up: Move up\n"
"Down: Move down\n"
"Left: Move left\n"
"Right: Move right\n"
"...\n"
"\n"
"Hints\n"
"\n"
"Use the map to your advantage. You can go through walls that appear "
"to be hollow. Try to anticipate where balls will be. Remember that "
"they bounce off walls in the opposite direction. To stop, move "
"against a wall.";
static int _db_help_quit;
static void
_db_help_triangle(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a,
int x_min, int y_min, int dir)
{
int i;
int y;
int x;
SDL_Point points[(16 * (16 + 2)) / 4];
i = 0;
for (y = 0; y < (16 / 2); ++y) {
for (x = y; x < (16 - y); ++x) {
points[i].x = x_min + x;
if (dir > 0) {
points[i].y = y_min + y;
} else {
points[i].y = y_min + (16 / 2) - 1 - y;
}
++i;
}
}
SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_RenderDrawPoints(renderer, points, i);
}
int
db_help(void)
{
char *font_path;
SDL_Renderer *renderer;
TTF_Font *font;
SDL_Color color;
SDL_Surface *surface;
SDL_Texture *texture;
SDL_Rect text_src_rect;
SDL_Rect text_dst_rect;
SDL_Rect up_rect;
SDL_Rect dn_rect;
int up_over;
int dn_over;
SDL_Event event;
font_path = db_strcat(db_get_fonts_dir(), "/UbuntuTitling-Bold.ttf");
renderer = db_get_renderer();
font = TTF_OpenFont(font_path, 16);
if (font == NULL) {
db_err("Failed to open font (%s)", TTF_GetError());
free(font_path);
return -1;
}
color.r = 0x00;
color.g = 0x00;
color.b = 0xFF;
color.a = 0xFF;
surface = TTF_RenderText_Blended_Wrapped(font, _db_help_text, color,
592);
if (surface == NULL) {
db_err("Failed to create surface (%s)", TTF_GetError());
return -1;
}
TTF_CloseFont(font);
texture = SDL_CreateTextureFromSurface(renderer, surface);
if (texture == NULL) {
db_err("Failed to create texture (%s)", SDL_GetError());
return -1;
}
text_src_rect.x = 0;
text_src_rect.y = 0;
text_src_rect.w = 592;
text_src_rect.h = 448;
text_dst_rect.x = 16;
text_dst_rect.y = 16;
text_dst_rect.w = 592;
text_dst_rect.h = 448;
up_rect.x = 608;
up_rect.y = 16;
up_rect.w = 16;
up_rect.h = 8;
dn_rect.x = 608;
dn_rect.y = 456;
dn_rect.w = 16;
dn_rect.h = 8;
up_over = 0;
dn_over = 0;
_db_help_quit = 0;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
_db_help_quit = 2;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_UP:
text_src_rect.y -= 16;
if (text_src_rect.y < 0) {
text_src_rect.y = 0;
}
break;
case SDLK_DOWN:
text_src_rect.y += 16;
if (text_src_rect.y > surface->h
-
text_src_rect.h)
{
text_src_rect.y =
surface->h -
text_src_rect.h;
}
break;
case SDLK_HOME:
text_src_rect.y = 0;
break;
case SDLK_END:
text_src_rect.y = surface->h -
text_src_rect.h;
break;
case SDLK_ESCAPE:
case SDLK_RETURN:
case SDLK_KP_ENTER:
_db_help_quit = 1;
break;
default:
break;
}
break;
case SDL_MOUSEMOTION:
if (event.motion.state != 0) {
break;
}
if (db_pt_in_rect(event.motion.x,
event.motion.y,
&up_rect)) {
up_over = 1;
break;
} else {
up_over = 0;
}
if (db_pt_in_rect(event.motion.x,
event.motion.y,
&dn_rect)) {
dn_over = 1;
break;
} else {
dn_over = 0;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button != SDL_BUTTON_LEFT) {
break;
}
if (db_pt_in_rect(event.button.x,
event.button.y,
&up_rect)) {
text_src_rect.y -= 16;
if (text_src_rect.y < 0) {
text_src_rect.y = 0;
}
} else if (db_pt_in_rect(event.button.x,
event.button.y,
&dn_rect)) {
text_src_rect.y += 16;
if (text_src_rect.y > surface->h -
text_src_rect.h) {
text_src_rect.y = surface->h -
text_src_rect.h;
}
}
break;
default:
break;
}
if (_db_help_quit > 0) {
break;
}
SDL_SetRenderDrawColor(renderer, 0x7F, 0x7F, 0x7F, 0xFF);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture,
&text_src_rect, &text_dst_rect);
if (text_src_rect.y <= 0) {
_db_help_triangle(renderer,
0x3F, 0x3F, 0x7F, 0xFF, 608, 16, -1);
} else if (up_over == 1) {
_db_help_triangle(renderer,
0xFF, 0xFF, 0xFF, 0xFF, 608, 16, -1);
} else {
_db_help_triangle(renderer,
0x00, 0x00, 0xFF, 0xFF, 608, 16, -1);
}
if (text_src_rect.y >= surface->h - text_src_rect.h) {
_db_help_triangle(renderer,
0x3F, 0x3F, 0x7F, 0xFF, 608, 456, 1);
} else if (dn_over == 1) {
_db_help_triangle(renderer,
0xFF, 0xFF, 0xFF, 0xFF, 608, 456, 1);
} else {
_db_help_triangle(renderer,
0x00, 0x00, 0xFF, 0xFF, 608, 456, 1);
}
SDL_RenderPresent(renderer);
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
return _db_help_quit - 1;
}