v1.0.0-dev
|
@ -0,0 +1,3 @@
|
||||||
|
.vscode
|
||||||
|
build
|
||||||
|
spaceshooter
|
|
@ -0,0 +1,20 @@
|
||||||
|
![logo](images/logo.png)
|
||||||
|
|
||||||
|
A space shooter based on the [lessons](https://www.youtube.com/watch?v=98hTrHen7IA&list=PL9333715188CD7669) of [Mike Geig](https://twitter.com/mikegeig). Main innovations: game menu, network game support. [Demonstration](https://www.youtube.com/watch?v=6D-t6TV8ITs) of the game.
|
||||||
|
|
||||||
|
This game is under development. Currently, the repository has been suspended since 2020.
|
||||||
|
|
||||||
|
![menu](images/menu.png)
|
||||||
|
|
||||||
|
![game](images/game.png)
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -B . -S ../game
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
The basic data needed to run the game is located in the [data](data/) directory.
|
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 345 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 159 KiB |
|
@ -0,0 +1,84 @@
|
||||||
|
linux-vdso.so.1 (0x00007fffea1d0000)
|
||||||
|
liballegro.so.5.2 => /usr/lib/liballegro.so.5.2 (0x00007f55d8202000)
|
||||||
|
liballegro_primitives.so.5.2 => /usr/lib/liballegro_primitives.so.5.2 (0x00007f55d81ec000)
|
||||||
|
liballegro_dialog.so.5.2 => /usr/lib/liballegro_dialog.so.5.2 (0x00007f55d81de000)
|
||||||
|
liballegro_image.so.5.2 => /usr/lib/liballegro_image.so.5.2 (0x00007f55d81cd000)
|
||||||
|
liballegro_font.so.5.2 => /usr/lib/liballegro_font.so.5.2 (0x00007f55d81c0000)
|
||||||
|
liballegro_ttf.so.5.2 => /usr/lib/liballegro_ttf.so.5.2 (0x00007f55d81b8000)
|
||||||
|
liballegro_audio.so.5.2 => /usr/lib/liballegro_audio.so.5.2 (0x00007f55d8199000)
|
||||||
|
liballegro_acodec.so.5.2 => /usr/lib/liballegro_acodec.so.5.2 (0x00007f55d818f000)
|
||||||
|
libenet.so.7 => /usr/lib/libenet.so.7 (0x00007f55d8182000)
|
||||||
|
libc.so.6 => /usr/lib/libc.so.6 (0x00007f55d7e00000)
|
||||||
|
libm.so.6 => /usr/lib/libm.so.6 (0x00007f55d8099000)
|
||||||
|
libX11.so.6 => /usr/lib/libX11.so.6 (0x00007f55d7c7b000)
|
||||||
|
libXcursor.so.1 => /usr/lib/libXcursor.so.1 (0x00007f55d8089000)
|
||||||
|
libXpm.so.4 => /usr/lib/libXpm.so.4 (0x00007f55d8072000)
|
||||||
|
libXi.so.6 => /usr/lib/libXi.so.6 (0x00007f55d805e000)
|
||||||
|
libXinerama.so.1 => /usr/lib/libXinerama.so.1 (0x00007f55d8059000)
|
||||||
|
libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0x00007f55d804c000)
|
||||||
|
libOpenGL.so.0 => /usr/lib/libOpenGL.so.0 (0x00007f55d801f000)
|
||||||
|
libGLX.so.0 => /usr/lib/libGLX.so.0 (0x00007f55d7c47000)
|
||||||
|
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f55d8345000)
|
||||||
|
libgtk-x11-2.0.so.0 => /usr/lib/libgtk-x11-2.0.so.0 (0x00007f55d7600000)
|
||||||
|
libgdk-x11-2.0.so.0 => /usr/lib/libgdk-x11-2.0.so.0 (0x00007f55d7b81000)
|
||||||
|
libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0 (0x00007f55d7b4f000)
|
||||||
|
libpango-1.0.so.0 => /usr/lib/libpango-1.0.so.0 (0x00007f55d7ad0000)
|
||||||
|
libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x00007f55d7a70000)
|
||||||
|
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x00007f55d74ba000)
|
||||||
|
libpng16.so.16 => /usr/lib/libpng16.so.16 (0x00007f55d747d000)
|
||||||
|
libjpeg.so.8 => /usr/lib/libjpeg.so.8 (0x00007f55d73fc000)
|
||||||
|
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00007f55d72ff000)
|
||||||
|
libpulse-simple.so.0 => /usr/lib/libpulse-simple.so.0 (0x00007f55d8015000)
|
||||||
|
libpulse.so.0 => /usr/lib/libpulse.so.0 (0x00007f55d72b4000)
|
||||||
|
libopenal.so.1 => /usr/lib/libopenal.so.1 (0x00007f55d716d000)
|
||||||
|
libFLAC.so.12 => /usr/lib/libFLAC.so.12 (0x00007f55d70f3000)
|
||||||
|
libvorbisfile.so.3 => /usr/lib/libvorbisfile.so.3 (0x00007f55d7a5f000)
|
||||||
|
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007f55d70c5000)
|
||||||
|
libXrender.so.1 => /usr/lib/libXrender.so.1 (0x00007f55d8006000)
|
||||||
|
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00007f55d70bd000)
|
||||||
|
libXext.so.6 => /usr/lib/libXext.so.6 (0x00007f55d70a4000)
|
||||||
|
libGLdispatch.so.0 => /usr/lib/libGLdispatch.so.0 (0x00007f55d6fea000)
|
||||||
|
libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0x00007f55d6fe3000)
|
||||||
|
libpangocairo-1.0.so.0 => /usr/lib/libpangocairo-1.0.so.0 (0x00007f55d6fd2000)
|
||||||
|
libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0 (0x00007f55d6fa9000)
|
||||||
|
libcairo.so.2 => /usr/lib/libcairo.so.2 (0x00007f55d6e3c000)
|
||||||
|
libgio-2.0.so.0 => /usr/lib/libgio-2.0.so.0 (0x00007f55d6c53000)
|
||||||
|
libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0x00007f55d6c39000)
|
||||||
|
libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0x00007f55d6bed000)
|
||||||
|
libXcomposite.so.1 => /usr/lib/libXcomposite.so.1 (0x00007f55d6be8000)
|
||||||
|
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00007f55d6be3000)
|
||||||
|
libfribidi.so.0 => /usr/lib/libfribidi.so.0 (0x00007f55d6bc3000)
|
||||||
|
libharfbuzz.so.0 => /usr/lib/libharfbuzz.so.0 (0x00007f55d6ac8000)
|
||||||
|
libffi.so.7 => /usr/lib/libffi.so.7 (0x00007f55d6abc000)
|
||||||
|
libpcre2-8.so.0 => /usr/lib/libpcre2-8.so.0 (0x00007f55d6a21000)
|
||||||
|
libz.so.1 => /usr/lib/libz.so.1 (0x00007f55d6a04000)
|
||||||
|
libbz2.so.1.0 => /usr/lib/libbz2.so.1.0 (0x00007f55d69e4000)
|
||||||
|
libbrotlidec.so.1 => /usr/lib/libbrotlidec.so.1 (0x00007f55d69d6000)
|
||||||
|
libpulsecommon-15.0.so => /usr/lib64/pulseaudio/libpulsecommon-15.0.so (0x00007f55d6960000)
|
||||||
|
libdbus-1.so.3 => /usr/lib/libdbus-1.so.3 (0x00007f55d691d000)
|
||||||
|
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f55d6600000)
|
||||||
|
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f55d68fa000)
|
||||||
|
libogg.so.0 => /usr/lib/libogg.so.0 (0x00007f55d68ec000)
|
||||||
|
libvorbis.so.0 => /usr/lib/libvorbis.so.0 (0x00007f55d68a9000)
|
||||||
|
libXau.so.6 => /usr/lib/libXau.so.6 (0x00007f55d68a4000)
|
||||||
|
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007f55d689c000)
|
||||||
|
libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0x00007f55d6506000)
|
||||||
|
libEGL.so.1 => /usr/lib/libEGL.so.1 (0x00007f55d6883000)
|
||||||
|
libxcb-shm.so.0 => /usr/lib/libxcb-shm.so.0 (0x00007f55d687e000)
|
||||||
|
libxcb-render.so.0 => /usr/lib/libxcb-render.so.0 (0x00007f55d686d000)
|
||||||
|
libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f55d647f000)
|
||||||
|
libmount.so.1 => /usr/lib/libmount.so.1 (0x00007f55d6420000)
|
||||||
|
libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f55d63f5000)
|
||||||
|
libgraphite2.so.3 => /usr/lib/libgraphite2.so.3 (0x00007f55d63d1000)
|
||||||
|
libbrotlicommon.so.1 => /usr/lib/libbrotlicommon.so.1 (0x00007f55d63ae000)
|
||||||
|
libsndfile.so.1 => /usr/lib/libsndfile.so.1 (0x00007f55d631f000)
|
||||||
|
libsystemd.so.0 => /usr/lib/libsystemd.so.0 (0x00007f55d626c000)
|
||||||
|
libmvec.so.1 => /usr/lib/libmvec.so.1 (0x00007f55d6172000)
|
||||||
|
libblkid.so.1 => /usr/lib/libblkid.so.1 (0x00007f55d611c000)
|
||||||
|
libvorbisenc.so.2 => /usr/lib/libvorbisenc.so.2 (0x00007f55d6068000)
|
||||||
|
libopus.so.0 => /usr/lib/libopus.so.0 (0x00007f55d5ffa000)
|
||||||
|
libcap.so.2 => /usr/lib/libcap.so.2 (0x00007f55d685d000)
|
||||||
|
libgcrypt.so.20 => /usr/lib/libgcrypt.so.20 (0x00007f55d5ed6000)
|
||||||
|
liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007f55d5ea6000)
|
||||||
|
libzstd.so.1 => /usr/lib/libzstd.so.1 (0x00007f55d5dcf000)
|
||||||
|
libgpg-error.so.0 => /usr/lib/libgpg-error.so.0 (0x00007f55d5da8000)
|
|
@ -0,0 +1,59 @@
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(spaceshooter)
|
||||||
|
|
||||||
|
include_directories("lib/" "network/" "objects/")
|
||||||
|
|
||||||
|
set(SRC_GAME
|
||||||
|
autors.c
|
||||||
|
common.c
|
||||||
|
data.c
|
||||||
|
gameover.c
|
||||||
|
main.c
|
||||||
|
menu.c
|
||||||
|
networkcreate.c
|
||||||
|
networkgame.c
|
||||||
|
networkjoin.c
|
||||||
|
networklist.c
|
||||||
|
networkmode.c
|
||||||
|
networkout.c
|
||||||
|
networkparty.c
|
||||||
|
pause.c
|
||||||
|
single.c)
|
||||||
|
|
||||||
|
set(SRC_LIB
|
||||||
|
lib/common.c
|
||||||
|
lib/event.c
|
||||||
|
lib/instance.c
|
||||||
|
lib/interface.c
|
||||||
|
lib/media.c
|
||||||
|
lib/message.c
|
||||||
|
lib/screen.c
|
||||||
|
lib/timer.c)
|
||||||
|
|
||||||
|
set(SRC_NETWORK network/network.c)
|
||||||
|
|
||||||
|
set(SRC_OBJECTS objects/objects.c)
|
||||||
|
|
||||||
|
find_library(ALLEGRO_LIB NAMES allegro)
|
||||||
|
find_library(ALLEGRO_PRIMITIVES_LIB NAMES allegro_primitives)
|
||||||
|
find_library(ALLEGRO_DIALOG_LIB NAMES allegro_dialog)
|
||||||
|
find_library(ALLEGRO_IMAGE_LIB allegro_image)
|
||||||
|
find_library(ALLEGRO_FONT_LIB allegro_font)
|
||||||
|
find_library(ALLEGRO_TTF_LIB allegro_ttf)
|
||||||
|
find_library(ALLEGRO_AUDIO_LIB allegro_audio)
|
||||||
|
find_library(ALLEGRO_ACODEC_LIB allegro_acodec)
|
||||||
|
find_library(ENET_LIB enet)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC_OBJECTS} ${SRC_LIB} ${SRC_NETWORK} ${SRC_GAME})
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
${ALLEGRO_LIB}
|
||||||
|
${ALLEGRO_PRIMITIVES_LIB}
|
||||||
|
${ALLEGRO_DIALOG_LIB}
|
||||||
|
${ALLEGRO_IMAGE_LIB}
|
||||||
|
${ALLEGRO_COLOR_LIB}
|
||||||
|
${ALLEGRO_FONT_LIB}
|
||||||
|
${ALLEGRO_TTF_LIB}
|
||||||
|
${ALLEGRO_AUDIO_LIB}
|
||||||
|
${ALLEGRO_ACODEC_LIB}
|
||||||
|
${ENET_LIB})
|
|
@ -0,0 +1,142 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "autors.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void autors_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
autors_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
autors_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
autors_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void autors_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void autors_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[AUTORS]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[AUTORS]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 6)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 6) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 6) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void autors_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_AUTORS_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* File: autors.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.07
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_autors
|
||||||
|
#define client_autors
|
||||||
|
|
||||||
|
enum autors_buttons
|
||||||
|
{
|
||||||
|
BUTTON_AUTORS_OUT // output
|
||||||
|
};
|
||||||
|
|
||||||
|
void autors_handling(CLIENT_DATA* data);
|
||||||
|
void autors_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void autors_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void autors_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,834 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "single.h"
|
||||||
|
#include "networkmode.h"
|
||||||
|
#include "networkcreate.h"
|
||||||
|
#include "networkjoin.h"
|
||||||
|
#include "networklist.h"
|
||||||
|
#include "networkparty.h"
|
||||||
|
#include "networkgame.h"
|
||||||
|
#include "networkout.h"
|
||||||
|
#include "autors.h"
|
||||||
|
#include "pause.h"
|
||||||
|
#include "gameover.h"
|
||||||
|
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void cl_init_interfaces(CLIENT_PAIRING* pairing)
|
||||||
|
{
|
||||||
|
pairing->interface[MENU] = cl_create_interface(2, 5, 0);
|
||||||
|
pairing->interface[SINGLE] = cl_create_interface(3, 0, 0);
|
||||||
|
pairing->interface[NETWORKMODE] = cl_create_interface(0, 3, 0);
|
||||||
|
pairing->interface[NETWORKCREATE] = cl_create_interface(0, 2, 2);
|
||||||
|
pairing->interface[NETWORKJOIN] = cl_create_interface(0, 2, 1);
|
||||||
|
pairing->interface[NETWORKLIST] = cl_create_interface(0, 1, 0);
|
||||||
|
pairing->interface[NETWORKPARTY] = cl_create_interface(0, 4, 0);
|
||||||
|
pairing->interface[NETWORKGAME] = cl_create_interface(3, 0, 0);
|
||||||
|
pairing->interface[NETWORKOUT] = cl_create_interface(0, 2, 0);
|
||||||
|
pairing->interface[SETTINGS] = cl_create_interface(0, 0, 0);
|
||||||
|
pairing->interface[AUTORS] = cl_create_interface(0, 1, 0); // 0 background size (background copies)
|
||||||
|
pairing->interface[PAUSE] = cl_create_interface(0, 2, 0); // 0 background size (background copies)
|
||||||
|
pairing->interface[GAMEOVER] = cl_create_interface(0, 1, 0); // 0 background size (background copies)
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_load_media(CLIENT_MEDIA* media)
|
||||||
|
{
|
||||||
|
cl_load_bitmap(media, BG1, "data/bitmaps/starBG.png");
|
||||||
|
cl_load_bitmap(media, BG2, "data/bitmaps/starFG.png");
|
||||||
|
cl_load_bitmap(media, BG3, "data/bitmaps/starMG.png");
|
||||||
|
cl_load_bitmap(media, SHIP_R, "data/bitmaps/ship_red.png");
|
||||||
|
al_convert_mask_to_alpha(media->bitmaps[SHIP_R]->al_bitmap, al_map_rgb(255, 0, 255));
|
||||||
|
cl_load_bitmap(media, SHIP_G, "data/bitmaps/ship_green.png");
|
||||||
|
al_convert_mask_to_alpha(media->bitmaps[SHIP_G]->al_bitmap, al_map_rgb(255, 0, 255));
|
||||||
|
cl_load_bitmap(media, SHIP_Y, "data/bitmaps/ship_yellow.png");
|
||||||
|
al_convert_mask_to_alpha(media->bitmaps[SHIP_Y]->al_bitmap, al_map_rgb(255, 0, 255));
|
||||||
|
cl_load_bitmap(media, COMET, "data/bitmaps/comet.png");
|
||||||
|
cl_load_bitmap(media, EXPLOSION, "data/bitmaps/explosion.png");
|
||||||
|
cl_load_font(media, FONT_SAC60, "data/fonts/space_age_cyrillic.ttf", 60);
|
||||||
|
cl_load_font(media, FONT_SAC80, "data/fonts/space_age_cyrillic.ttf", 80);
|
||||||
|
cl_load_font(media, FONT_PS2P30, "data/fonts/Press_Start_2P.ttf", 30);
|
||||||
|
cl_load_font(media, FONT_PS2P40, "data/fonts/Press_Start_2P.ttf", 40);
|
||||||
|
cl_load_sample(media, SAMPLE_BOOM, "data/samples/boom.ogg");
|
||||||
|
cl_load_sample(media, SAMPLE_SHOT, "data/samples/shot.ogg");
|
||||||
|
cl_load_sample(media, SAMPLE_MENU, "data/samples/menu.ogg");
|
||||||
|
cl_load_sample(media, SAMPLE_GAME, "data/samples/game.ogg");
|
||||||
|
cl_load_sample(media, SAMPLE_BUTTON, "data/samples/button.ogg");
|
||||||
|
cl_load_sample(media, SAMPLE_ENTER, "data/samples/enter.ogg");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_init_media(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_init_sample_instance(data, INSTANCE_MENU, SAMPLE_MENU);
|
||||||
|
cl_init_sample_instance(data, INSTANCE_GAME, SAMPLE_GAME);
|
||||||
|
/************************************************************
|
||||||
|
* MENU
|
||||||
|
***********************************************************/
|
||||||
|
cl_init_background(data, MENU, BG1, 0, 0, 1, 0, -1, 1);
|
||||||
|
cl_init_background(data, MENU, BG2, 0, 0, 5, 0, -1, 1);
|
||||||
|
cl_init_header(data, MENU, FONT_SAC80, "Космический шутер");
|
||||||
|
menu_init_button(data, BUTTON_MENU_SINGLE, FONT_SAC60, "Одиночная игра");
|
||||||
|
menu_init_button(data, BUTTON_MENU_NETWORK, FONT_SAC60, "Сетевая игра");
|
||||||
|
menu_init_button(data, BUTTON_MENU_SETTINGS, FONT_SAC60, "Настройки");
|
||||||
|
menu_init_button(data, BUTTON_MENU_AUTORS, FONT_SAC60, "Авторы");
|
||||||
|
menu_init_button(data, BUTTON_MENU_OUT, FONT_SAC60, "Выход");
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKMODE, MENU);
|
||||||
|
cl_init_header(data, NETWORKMODE, FONT_SAC80, "Сетевая игра");
|
||||||
|
networkmode_init_button(data, BUTTON_NETWORKMODE_CREATE, FONT_SAC60, "Создать");
|
||||||
|
networkmode_init_button(data, BUTTON_NETWORKMODE_JOIN, FONT_SAC60, "Присоединиться");
|
||||||
|
networkmode_init_button(data, BUTTON_NETWORKMODE_OUT, FONT_SAC60, "Назад в меню");
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK CREATE
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKCREATE, MENU);
|
||||||
|
cl_init_header(data, NETWORKCREATE, FONT_SAC80, "Создание сетевой игры");
|
||||||
|
networkcreate_init_field(data, FIELD_NETWORKCREATE_NICKNAME, FONT_PS2P40, "Никнейм:");
|
||||||
|
networkcreate_init_field(data, FIELD_NETWORKCREATE_GAMENAME, FONT_PS2P40, "Название игры:");
|
||||||
|
networkcreate_init_button(data, BUTTON_NETWORKCREATE_CREATE, FONT_SAC60, "Создать игру");
|
||||||
|
networkcreate_init_button(data, BUTTON_NETWORKCREATE_OUT, FONT_SAC60, "Назад");
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK JOIN
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKJOIN, MENU);
|
||||||
|
cl_init_header(data, NETWORKJOIN, FONT_SAC80, "Присоединиться к игре");
|
||||||
|
networkjoin_init_field(data, FIELD_NETWORKJOIN_NICKNAME, FONT_PS2P40, "Никнейм:");
|
||||||
|
networkjoin_init_button(data, BUTTON_NETWORKJOIN_CREATE, FONT_SAC60, "Найти игру");
|
||||||
|
networkjoin_init_button(data, BUTTON_NETWORKJOIN_OUT, FONT_SAC60, "Назад");
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK LIST
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKLIST, MENU);
|
||||||
|
cl_init_header(data, NETWORKLIST, FONT_SAC80, "Список серверов");
|
||||||
|
networklist_init_button(data, BUTTON_NETWORKLIST_OUT, FONT_SAC60, "Назад");
|
||||||
|
networklist_init_list(data, FONT_PS2P40);
|
||||||
|
/************************************************************
|
||||||
|
* AUTORS
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, AUTORS, MENU);
|
||||||
|
cl_init_header(data, AUTORS, FONT_SAC80, "Авторы");
|
||||||
|
autors_init_button(data, BUTTON_AUTORS_OUT, FONT_SAC60, "Назад в меню");
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK PARTY
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKPARTY, MENU);
|
||||||
|
cl_init_header(data, NETWORKPARTY, FONT_SAC80, "Новая игра");
|
||||||
|
networkparty_init_button(data, BUTTON_NETWORKPARTY_START, FONT_SAC60, "Начать");
|
||||||
|
networkparty_init_button(data, BUTTON_NETWORKPARTY_READY, FONT_SAC60, "Готов");
|
||||||
|
networkparty_init_button(data, BUTTON_NETWORKPARTY_UNREADY, FONT_SAC60, "Не готов");
|
||||||
|
networkparty_init_button(data, BUTTON_NETWORKPARTY_OUT, FONT_SAC60, "Назад");
|
||||||
|
networkparty_init_list(data, FONT_PS2P40);
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK OUT
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, NETWORKOUT, NETWORKGAME);
|
||||||
|
cl_init_header(data, NETWORKOUT, FONT_SAC80, "Режим сетевой игры");
|
||||||
|
networkout_init_button(data, BUTTON_NETWORKOUT_BACK, FONT_SAC60, "Продолжить");
|
||||||
|
networkout_init_button(data, BUTTON_NETWORKOUT_MENU, FONT_SAC60, "Выйти в меню");
|
||||||
|
/************************************************************
|
||||||
|
* PAUSE
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, PAUSE, MENU);
|
||||||
|
cl_init_header(data, PAUSE, FONT_SAC80, "Пауза");
|
||||||
|
pause_init_button(data, BUTTON_PAUSE_BACK, FONT_SAC60, "Продолжить");
|
||||||
|
pause_init_button(data, BUTTON_PAUSE_MENU, FONT_SAC60, "Выйти в меню");
|
||||||
|
/************************************************************
|
||||||
|
* GAMEOVER
|
||||||
|
***********************************************************/
|
||||||
|
cl_copy_background(data, GAMEOVER, MENU);
|
||||||
|
cl_init_header(data, GAMEOVER, FONT_SAC80, "Конец игры");
|
||||||
|
gameover_init_button(data, BUTTON_GAMEOVER_OUT, FONT_SAC60, "Выйти в меню");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_change_state(CLIENT_DATA* data, int state)
|
||||||
|
{
|
||||||
|
if(data->state == MENU && state == SINGLE)
|
||||||
|
{
|
||||||
|
/************************************************************
|
||||||
|
* CREATE GAME OBJECTS
|
||||||
|
***********************************************************/
|
||||||
|
cl_init_background(data, SINGLE, BG1, 0, 0, 1, 0, -1, 1);
|
||||||
|
cl_init_background(data, SINGLE, BG2, 0, 0, 5, 0, -1, 1);
|
||||||
|
cl_init_background(data, SINGLE, BG3, 0, 0, 3, 0, -1, 1);
|
||||||
|
|
||||||
|
cl_init_objects(data);
|
||||||
|
}
|
||||||
|
else if((data->state == PAUSE || data->state == GAMEOVER) && state == MENU)
|
||||||
|
/************************************************************
|
||||||
|
* DESTROY GAME OBJECTS
|
||||||
|
***********************************************************/
|
||||||
|
cl_destroy_objects(&data->objects);
|
||||||
|
else if(data->state == NETWORKCREATE && state == NETWORKPARTY)
|
||||||
|
{
|
||||||
|
cl_create_enet(&data->enet);
|
||||||
|
if(data->enet.connect)
|
||||||
|
cl_send_message_create(data);
|
||||||
|
else
|
||||||
|
state = NETWORKCREATE;
|
||||||
|
}
|
||||||
|
else if(data->state == NETWORKJOIN && state == NETWORKLIST)
|
||||||
|
{
|
||||||
|
cl_create_enet(&data->enet);
|
||||||
|
if(data->enet.connect)
|
||||||
|
cl_send_message_join(data);
|
||||||
|
else
|
||||||
|
state = NETWORKJOIN;
|
||||||
|
}
|
||||||
|
else if((data->state == NETWORKPARTY && state == NETWORKMODE) ||
|
||||||
|
(data->state == NETWORKLIST && state == NETWORKMODE))
|
||||||
|
{
|
||||||
|
cl_disconnect_enet(&data->enet);
|
||||||
|
}
|
||||||
|
else if(data->state == NETWORKOUT && state == NETWORKMODE)
|
||||||
|
{
|
||||||
|
cl_disconnect_enet(&data->enet);
|
||||||
|
cl_destroy_objects(&data->objects);
|
||||||
|
}
|
||||||
|
else if(data->state == NETWORKPARTY && state == NETWORKGAME)
|
||||||
|
{
|
||||||
|
/************************************************************
|
||||||
|
* CREATE GAME OBJECTS
|
||||||
|
***********************************************************/
|
||||||
|
cl_init_background(data, NETWORKGAME, BG1, 0, 0, 1, 0, -1, 1);
|
||||||
|
cl_init_background(data, NETWORKGAME, BG2, 0, 0, 5, 0, -1, 1);
|
||||||
|
cl_init_background(data, NETWORKGAME, BG3, 0, 0, 3, 0, -1, 1);
|
||||||
|
|
||||||
|
networkgame_create_objects(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data->state = state;
|
||||||
|
|
||||||
|
cl_change_sample_instance(data, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SAMPLE INSTANCE
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_init_sample_instance(CLIENT_DATA* data, int key_instance, int key_sample)
|
||||||
|
{
|
||||||
|
cl_add_instance(
|
||||||
|
data->sound.instance[key_instance],
|
||||||
|
data->media.samples[key_sample]->al_sapmle,
|
||||||
|
ALLEGRO_PLAYMODE_LOOP,
|
||||||
|
data->settings.music_gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_change_sample_instance(CLIENT_DATA* data, int state)
|
||||||
|
{
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
case MENU:
|
||||||
|
case NETWORKMODE:
|
||||||
|
case NETWORKCREATE:
|
||||||
|
case NETWORKJOIN:
|
||||||
|
case NETWORKLIST:
|
||||||
|
case NETWORKPARTY:
|
||||||
|
case SETTINGS:
|
||||||
|
case AUTORS:
|
||||||
|
if(data->sound.current_instance != INSTANCE_MENU)
|
||||||
|
{
|
||||||
|
al_stop_sample_instance(data->sound.instance[INSTANCE_GAME]->al_instance);
|
||||||
|
al_play_sample_instance(data->sound.instance[INSTANCE_MENU]->al_instance);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SINGLE:
|
||||||
|
case NETWORKGAME:
|
||||||
|
case NETWORKOUT:
|
||||||
|
case PAUSE:
|
||||||
|
case GAMEOVER:
|
||||||
|
if(data->sound.current_instance != INSTANCE_GAME)
|
||||||
|
{
|
||||||
|
al_stop_sample_instance(data->sound.instance[INSTANCE_MENU]->al_instance);
|
||||||
|
al_play_sample_instance(data->sound.instance[INSTANCE_GAME]->al_instance);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_play_sound(CLIENT_DATA* data, int key_sample)
|
||||||
|
{
|
||||||
|
al_play_sample(data->media.samples[key_sample]->al_sapmle, data->settings.effects_gain, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BACKGROUND
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_init_background(CLIENT_DATA* data, int key_state, int key_bitmap, float x, float y, float vel_x, float vel_y, int dir_x, int dir_y)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[key_state]->background_size > key_bitmap)
|
||||||
|
cl_add_interface_background(
|
||||||
|
data->pairing.interface[key_state]->background[key_bitmap],
|
||||||
|
data->media.bitmaps[key_bitmap],
|
||||||
|
dir_x, dir_y, vel_x, vel_y, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_copy_background(CLIENT_DATA* data, int dir_key_state, int src_key_state)
|
||||||
|
{
|
||||||
|
data->pairing.interface[dir_key_state]->background = data->pairing.interface[src_key_state]->background;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_draw_background(CLIENT_DATA* data, int key_bitmap)
|
||||||
|
{
|
||||||
|
CLIENT_BACKGROUND_PAGE* bg = data->pairing.interface[data->state]->background[key_bitmap];
|
||||||
|
|
||||||
|
al_draw_bitmap(bg->bitmap->al_bitmap, bg->x, bg->y, 0);
|
||||||
|
al_draw_bitmap(bg->bitmap->al_bitmap, bg->x + bg->bitmap->width, bg->y, 0);
|
||||||
|
|
||||||
|
if(bg->x + bg->bitmap->width + bg->bitmap->width < data->screen.width)
|
||||||
|
al_draw_bitmap(bg->bitmap->al_bitmap, bg->x + bg->bitmap->width + bg->bitmap->width, bg->y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_update_background(CLIENT_DATA* data, int key_bitmap)
|
||||||
|
{
|
||||||
|
CLIENT_BACKGROUND_PAGE* bg = data->pairing.interface[data->state]->background[key_bitmap];
|
||||||
|
|
||||||
|
bg->x += bg->vel_x * bg->dir_x;
|
||||||
|
if(bg->x + bg->bitmap->width < 0)
|
||||||
|
bg->x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HEADER
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_init_header(CLIENT_DATA* data, int key_state, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_header(
|
||||||
|
&data->pairing.interface[key_state]->header,
|
||||||
|
data->media.fonts[key_font]->al_font,
|
||||||
|
data->screen.width / 2,
|
||||||
|
block_size - data->media.fonts[key_font]->size / 2,
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_draw_header(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_HEADER header = data->pairing.interface[data->state]->header;
|
||||||
|
|
||||||
|
al_draw_text(header.al_font, al_map_rgb(255, 255, 255), header.x, header.y, ALLEGRO_ALIGN_CENTRE, header.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
// use with mouse event
|
||||||
|
void cl_update_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
if(data->screen.fullscreen)
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x / data->screen.scale_factor_x - data->screen.pos_x;
|
||||||
|
my = data->event.current.mouse.y / data->screen.scale_factor_y - data->screen.pos_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x;
|
||||||
|
my = data->event.current.mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_BUTTON* btn = interface->button[i];
|
||||||
|
|
||||||
|
if(!btn->active) continue;
|
||||||
|
|
||||||
|
if(btn->b_sx < mx && btn->b_dx > mx && btn->b_sy < my && btn->b_dy > my)
|
||||||
|
{
|
||||||
|
if(!btn->selected)
|
||||||
|
cl_play_sound(data, SAMPLE_BUTTON);
|
||||||
|
|
||||||
|
btn->selected = true;
|
||||||
|
interface->selected = SELECTED_BUTTON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
btn->selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// use with key
|
||||||
|
void cl_select_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
bool is_selected = false;
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
int count_active_button = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->active)
|
||||||
|
count_active_button++;
|
||||||
|
|
||||||
|
if(count_active_button)
|
||||||
|
{
|
||||||
|
CLIENT_BUTTON* button[count_active_button];
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->active)
|
||||||
|
button[iterator++] = interface->button[i];
|
||||||
|
|
||||||
|
for(int i = 0; i < count_active_button; i++)
|
||||||
|
if(button[i]->selected)
|
||||||
|
{
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
{
|
||||||
|
button[i]->selected = false;
|
||||||
|
|
||||||
|
if(i != 0)
|
||||||
|
button[i - 1]->selected = true;
|
||||||
|
else
|
||||||
|
button[count_active_button - 1]->selected = true;
|
||||||
|
}
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
{
|
||||||
|
button[i]->selected = false;
|
||||||
|
|
||||||
|
if(i == count_active_button - 1)
|
||||||
|
button[0]->selected = true;
|
||||||
|
else
|
||||||
|
button[i + 1]->selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_selected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_selected)
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
button[count_active_button - 1]->selected = true;
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
button[0]->selected = true;
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_BUTTON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_FIELD)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
if(interface->field[i]->selected)
|
||||||
|
{
|
||||||
|
interface->field[i]->enter = false;
|
||||||
|
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
{
|
||||||
|
interface->field[i]->selected = false;
|
||||||
|
|
||||||
|
if(i != 0)
|
||||||
|
interface->field[i - 1]->selected = true;
|
||||||
|
else
|
||||||
|
interface->field[interface->field_size - 1]->selected = true;
|
||||||
|
}
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
{
|
||||||
|
interface->field[i]->selected = false;
|
||||||
|
|
||||||
|
if(i == interface->field_size - 1)
|
||||||
|
interface->field[0]->selected = true;
|
||||||
|
else
|
||||||
|
interface->field[i + 1]->selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_selected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_selected)
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
interface->field[interface->field_size - 1]->selected = true;
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
interface->field[0]->selected = true;
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_BUTTON);
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_LIST)
|
||||||
|
{
|
||||||
|
int count_active_item = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(interface->list.item[i].active)
|
||||||
|
count_active_item++;
|
||||||
|
|
||||||
|
if(count_active_item)
|
||||||
|
{
|
||||||
|
CLIENT_LIST_ITEM* item[count_active_item];
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(interface->list.item[i].active)
|
||||||
|
item[iterator++] = &interface->list.item[i];
|
||||||
|
|
||||||
|
for(int i = 0; i < count_active_item; i++)
|
||||||
|
if(item[i]->selected)
|
||||||
|
{
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
{
|
||||||
|
item[i]->selected = false;
|
||||||
|
|
||||||
|
if(i != 0)
|
||||||
|
item[i - 1]->selected = true;
|
||||||
|
else
|
||||||
|
item[count_active_item - 1]->selected = true;
|
||||||
|
}
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
{
|
||||||
|
item[i]->selected = false;
|
||||||
|
|
||||||
|
if(i == count_active_item - 1)
|
||||||
|
item[0]->selected = true;
|
||||||
|
else
|
||||||
|
item[i + 1]->selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_selected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_selected)
|
||||||
|
if(data->keys[UP] && !data->keys[DOWN])
|
||||||
|
item[count_active_item - 1]->selected = true;
|
||||||
|
else if(data->keys[DOWN] && !data->keys[UP])
|
||||||
|
item[0]->selected = true;
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_BUTTON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_draw_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font)
|
||||||
|
{
|
||||||
|
CLIENT_BUTTON* btn = interface->button[i];
|
||||||
|
ALLEGRO_COLOR clr;
|
||||||
|
|
||||||
|
btn->active = true;
|
||||||
|
|
||||||
|
if(btn->selected)
|
||||||
|
clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_rectangle(btn->b_sx, btn->b_sy, btn->b_dx, btn->b_dy, clr);
|
||||||
|
al_draw_text(btn->al_font, al_map_rgb(255, 255, 255), btn->t_x, btn->t_y, ALLEGRO_ALIGN_CENTRE, btn->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* FIELD
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void cl_draw_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD* field = interface->field[i];
|
||||||
|
ALLEGRO_COLOR clr;
|
||||||
|
|
||||||
|
if(field->selected)
|
||||||
|
clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_text(field->al_font, al_map_rgb(255, 255, 255), field->d_x, field->d_y, 0, field->description);
|
||||||
|
al_draw_rectangle(field->f_sx, field->f_sy, field->f_dx, field->f_dy, clr, 2);
|
||||||
|
al_draw_text(field->al_font, al_map_rgb(255, 255, 255), field->ft_x, field->ft_y, 0, field->field_text);
|
||||||
|
|
||||||
|
if(field->enter)
|
||||||
|
al_draw_text(field->al_font, al_map_rgb(255, 255, 255), field->ft_x + field->char_number * field->char_size, field->ft_y, 0, "_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_update_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
if(data->screen.fullscreen)
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x / data->screen.scale_factor_x - data->screen.pos_x;
|
||||||
|
my = data->event.current.mouse.y / data->screen.scale_factor_y - data->screen.pos_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x;
|
||||||
|
my = data->event.current.mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD* field = interface->field[i];
|
||||||
|
|
||||||
|
if(field->f_sx < mx && field->f_dx > mx && field->f_sy < my && field->f_dy > my)
|
||||||
|
{
|
||||||
|
if(!field->selected)
|
||||||
|
cl_play_sound(data, SAMPLE_BUTTON);
|
||||||
|
|
||||||
|
field->selected = true;
|
||||||
|
interface->selected = SELECTED_FIELD;
|
||||||
|
}
|
||||||
|
else if(field->enter)
|
||||||
|
field->selected = true;
|
||||||
|
else
|
||||||
|
field->selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_enter_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
if(data->screen.fullscreen)
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x / data->screen.scale_factor_x - data->screen.pos_x;
|
||||||
|
my = data->event.current.mouse.y / data->screen.scale_factor_y - data->screen.pos_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x;
|
||||||
|
my = data->event.current.mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD* field = interface->field[i];
|
||||||
|
|
||||||
|
if(field->f_sx < mx && field->f_dx > mx && field->f_sy < my && field->f_dy > my)
|
||||||
|
field->enter = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field->enter = false;
|
||||||
|
field->selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_print_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
bool backspace = false;
|
||||||
|
char symbol = '\0';
|
||||||
|
|
||||||
|
switch(data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_A:
|
||||||
|
symbol = 'A';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_B:
|
||||||
|
symbol = 'B';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_C:
|
||||||
|
symbol = 'C';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_D:
|
||||||
|
symbol = 'D';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_E:
|
||||||
|
symbol = 'E';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_F:
|
||||||
|
symbol = 'F';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_G:
|
||||||
|
symbol = 'G';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_H:
|
||||||
|
symbol = 'H';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_I:
|
||||||
|
symbol = 'I';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_J:
|
||||||
|
symbol = 'J';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_K:
|
||||||
|
symbol = 'K';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_L:
|
||||||
|
symbol = 'L';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_M:
|
||||||
|
symbol = 'M';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_N:
|
||||||
|
symbol = 'N';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_O:
|
||||||
|
symbol = 'O';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_P:
|
||||||
|
symbol = 'P';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_Q:
|
||||||
|
symbol = 'Q';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_R:
|
||||||
|
symbol = 'R';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_S:
|
||||||
|
symbol = 'S';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_T:
|
||||||
|
symbol = 'T';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_U:
|
||||||
|
symbol = 'U';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_V:
|
||||||
|
symbol = 'V';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_W:
|
||||||
|
symbol = 'W';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_X:
|
||||||
|
symbol = 'X';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_Y:
|
||||||
|
symbol = 'Y';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_Z:
|
||||||
|
symbol = 'Z';
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_BACKSPACE:
|
||||||
|
backspace = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(symbol != '\0')
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD* field = interface->field[i];
|
||||||
|
|
||||||
|
if(field->enter && field->char_number < 18)
|
||||||
|
{
|
||||||
|
field->field_text[field->char_number] = symbol;
|
||||||
|
++field->char_number;
|
||||||
|
field->field_text[field->char_number] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(backspace)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD* field = interface->field[i];
|
||||||
|
|
||||||
|
if(field->enter && field->char_number > 0)
|
||||||
|
{
|
||||||
|
--field->char_number;
|
||||||
|
field->field_text[field->char_number] = symbol;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* LIST
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void cl_draw_list(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[data->state]->list;
|
||||||
|
|
||||||
|
// if(btn->selected)
|
||||||
|
// clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
// else
|
||||||
|
// clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_rectangle(list->sx, list->sy, list->dx, list->dy, al_map_rgba_f(0.2, 0.2, 0.2, 0.2), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_update_list(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[data->state]->list;
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
if(data->screen.fullscreen)
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x / data->screen.scale_factor_x - data->screen.pos_x;
|
||||||
|
my = data->event.current.mouse.y / data->screen.scale_factor_y - data->screen.pos_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mx = data->event.current.mouse.x;
|
||||||
|
my = data->event.current.mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if(!list->item[i].active) continue;
|
||||||
|
|
||||||
|
CLIENT_LIST_ITEM* item = &list->item[i];
|
||||||
|
|
||||||
|
if(item->sx_item < mx && item->dx_item > mx && item->sy_item < my && item->dy_item > my)
|
||||||
|
{
|
||||||
|
item->selected = true;
|
||||||
|
data->pairing.interface[data->state]->selected = SELECTED_LIST;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
item->selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void cl_send_message_create(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_NONE message;
|
||||||
|
|
||||||
|
CLIENT_FIELD** field = data->pairing.interface[data->state]->field;
|
||||||
|
|
||||||
|
message.display_height = data->screen.display_height;
|
||||||
|
message.display_width = data->screen.display_width;
|
||||||
|
message.scale_factor = data->screen.scale_factor;
|
||||||
|
strncpy(message.game_name, field[FIELD_NETWORKCREATE_GAMENAME]->field_text, 40);
|
||||||
|
strncpy(message.nickname, field[FIELD_NETWORKCREATE_NICKNAME]->field_text, 40);
|
||||||
|
message.is_creator = true;
|
||||||
|
message.is_ready = true;
|
||||||
|
message.state = STATE_PARTY;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_send_message_join(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_NONE message;
|
||||||
|
|
||||||
|
CLIENT_FIELD** field = data->pairing.interface[data->state]->field;
|
||||||
|
|
||||||
|
message.display_height = data->screen.display_height;
|
||||||
|
message.display_width = data->screen.display_width;
|
||||||
|
message.scale_factor = data->screen.scale_factor;
|
||||||
|
strncpy(message.nickname, field[FIELD_NETWORKJOIN_NICKNAME]->field_text, 40);
|
||||||
|
message.is_creator = false;
|
||||||
|
message.is_ready = false;
|
||||||
|
message.state = STATE_LIST;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* File: game.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_data
|
||||||
|
#define client_data
|
||||||
|
|
||||||
|
#include "lib/common.h"
|
||||||
|
#include "objects.h"
|
||||||
|
#include "network.h"
|
||||||
|
|
||||||
|
enum bitmaps
|
||||||
|
{
|
||||||
|
BG1,
|
||||||
|
BG2,
|
||||||
|
BG3,
|
||||||
|
SHIP_R,
|
||||||
|
SHIP_G,
|
||||||
|
SHIP_Y,
|
||||||
|
EXPLOSION,
|
||||||
|
COMET
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fonts
|
||||||
|
{
|
||||||
|
FONT_SAC60,
|
||||||
|
FONT_SAC80,
|
||||||
|
FONT_PS2P30,
|
||||||
|
FONT_PS2P40
|
||||||
|
};
|
||||||
|
|
||||||
|
enum samples
|
||||||
|
{
|
||||||
|
SAMPLE_BOOM,
|
||||||
|
SAMPLE_SHOT,
|
||||||
|
SAMPLE_MENU,
|
||||||
|
SAMPLE_GAME,
|
||||||
|
SAMPLE_BUTTON,
|
||||||
|
SAMPLE_ENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum instance
|
||||||
|
{
|
||||||
|
INSTANCE_MENU,
|
||||||
|
INSTANCE_GAME
|
||||||
|
};
|
||||||
|
|
||||||
|
enum states
|
||||||
|
{
|
||||||
|
MENU,
|
||||||
|
SINGLE,
|
||||||
|
NETWORKMODE,
|
||||||
|
NETWORKCREATE,
|
||||||
|
NETWORKJOIN,
|
||||||
|
NETWORKLIST,
|
||||||
|
NETWORKPARTY,
|
||||||
|
NETWORKGAME,
|
||||||
|
NETWORKOUT,
|
||||||
|
SETTINGS,
|
||||||
|
AUTORS,
|
||||||
|
PAUSE,
|
||||||
|
GAMEOVER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum keys
|
||||||
|
{
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
ENTER,
|
||||||
|
ESCAPE,
|
||||||
|
SPACE
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct cl_settings
|
||||||
|
{
|
||||||
|
float effects_gain;
|
||||||
|
float music_gain;
|
||||||
|
} CLIENT_SETTINGS;
|
||||||
|
|
||||||
|
typedef struct cl_data
|
||||||
|
{
|
||||||
|
CLIENT_SCREEN screen;
|
||||||
|
CLIENT_TIMER timer;
|
||||||
|
CLIENT_EVENT event;
|
||||||
|
CLIENT_MEDIA media;
|
||||||
|
CLIENT_PAIRING pairing;
|
||||||
|
CLIENT_OBJECTS objects;
|
||||||
|
CLIENT_NETWORK network;
|
||||||
|
CLIENT_ENET enet;
|
||||||
|
CLIENT_SOUND sound;
|
||||||
|
CLIENT_SETTINGS settings;
|
||||||
|
bool keys[7];
|
||||||
|
bool pause;
|
||||||
|
bool done;
|
||||||
|
bool render;
|
||||||
|
int state;
|
||||||
|
} CLIENT_DATA;
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* CREATE DATA PLAYER (MAIN OBJECT)
|
||||||
|
***********************************************************/
|
||||||
|
CLIENT_DATA* cl_create_data(CLIENT_DATA* data, CLIENT_PARAMETRS parametrs);
|
||||||
|
void cl_destroy_data(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* COMMON FUNCTION
|
||||||
|
***********************************************************/
|
||||||
|
void cl_init_interfaces(CLIENT_PAIRING* pairing);
|
||||||
|
void cl_load_media(CLIENT_MEDIA* media);
|
||||||
|
void cl_init_media(CLIENT_DATA* data);
|
||||||
|
void cl_change_state(CLIENT_DATA* data, int state);
|
||||||
|
/************************************************************
|
||||||
|
* SAMPLE INSTANCE
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_init_sample_instance(CLIENT_DATA* data, int key_instance, int key_sample);
|
||||||
|
static void cl_change_sample_instance(CLIENT_DATA* data, int state);
|
||||||
|
void cl_play_sound(CLIENT_DATA* data, int key_sample);
|
||||||
|
/************************************************************
|
||||||
|
* BACKGROUND
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_init_background(CLIENT_DATA* data, int key_state, int key_bitmap, float x, float y, float vel_x, float vel_y, int dir_x, int dir_y);
|
||||||
|
static void cl_copy_background(CLIENT_DATA* data, int dir_key_state, int src_key_state);
|
||||||
|
void cl_draw_background(CLIENT_DATA* data, int key_bitmap);
|
||||||
|
void cl_update_background(CLIENT_DATA* data, int key_bitmap);
|
||||||
|
/************************************************************
|
||||||
|
* HEADER
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_init_header(CLIENT_DATA* data, int key_state, int key_font, const char* text);
|
||||||
|
void cl_draw_header(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
void cl_update_button(CLIENT_DATA* data);
|
||||||
|
void cl_select_button(CLIENT_DATA* data);
|
||||||
|
void cl_draw_button(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* FIELD
|
||||||
|
***********************************************************/
|
||||||
|
void cl_draw_field(CLIENT_DATA* data);
|
||||||
|
void cl_update_field(CLIENT_DATA* data);
|
||||||
|
void cl_enter_field(CLIENT_DATA* data);
|
||||||
|
void cl_print_field(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* LIST
|
||||||
|
***********************************************************/
|
||||||
|
void cl_draw_list(CLIENT_DATA* data);
|
||||||
|
void cl_update_list(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* NETWORK
|
||||||
|
***********************************************************/
|
||||||
|
void cl_send_message_create(CLIENT_DATA* data);
|
||||||
|
void cl_send_message_join(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_DATA* cl_create_data(CLIENT_DATA* data, CLIENT_PARAMETRS parametrs)
|
||||||
|
{
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
data = (CLIENT_DATA*)malloc(sizeof(CLIENT_DATA));
|
||||||
|
show_message_error(data, "Failed to allocate space for CLIENT_DATA");
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_create_screen(&data->screen, parametrs.scale_factor, parametrs.fullscreen, parametrs.resolution, parametrs.width, parametrs.height, parametrs.FPS, parametrs.num_adapter);
|
||||||
|
cl_create_timer(&data->timer, parametrs.FPS);
|
||||||
|
cl_create_event(&data->event, &data->timer, &data->screen);
|
||||||
|
cl_create_media(&data->media, parametrs.bitmaps_size, parametrs.fonts_size, parametrs.samples_size);
|
||||||
|
cl_create_pairing(&data->pairing, parametrs.pairing_size);
|
||||||
|
cl_create_sound(&data->sound, parametrs.sound_size);
|
||||||
|
|
||||||
|
for(int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
data->keys[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pause = false;
|
||||||
|
data->done = false;
|
||||||
|
data->render = false;
|
||||||
|
data->state = 0;
|
||||||
|
data->enet.port = parametrs.enet_port;
|
||||||
|
strncpy(data->enet.host, parametrs.enet_host, 20);
|
||||||
|
data->settings.effects_gain = parametrs.effects_gain;
|
||||||
|
data->settings.music_gain = parametrs.music_gain;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_data(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_destroy_media(&data->media);
|
||||||
|
cl_destroy_event(&data->event);
|
||||||
|
cl_destroy_timer(&data->timer);
|
||||||
|
cl_destroy_screen(&data->screen);
|
||||||
|
cl_destroy_pairing(&data->pairing);
|
||||||
|
cl_destroy_sound(&data->sound);
|
||||||
|
free(data);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* File: game.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.05
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_game
|
||||||
|
#define client_game
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "single.h"
|
||||||
|
#include "networkmode.h"
|
||||||
|
#include "networkcreate.h"
|
||||||
|
#include "networkjoin.h"
|
||||||
|
#include "networklist.h"
|
||||||
|
#include "networkparty.h"
|
||||||
|
#include "networkgame.h"
|
||||||
|
#include "networkout.h"
|
||||||
|
#include "autors.h"
|
||||||
|
#include "pause.h"
|
||||||
|
#include "gameover.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "gameover.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void gameover_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
gameover_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
gameover_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
cl_update_button(data);
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
gameover_push_button(data);
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void gameover_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
gameover_draw_statistic(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void gameover_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[GAMEOVER]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[GAMEOVER]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 6)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 6) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 6) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gameover_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_GAMEOVER_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gameover_draw_statistic(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
ALLEGRO_FONT* font = data->media.fonts[FONT_PS2P40]->al_font;
|
||||||
|
ALLEGRO_COLOR color = al_map_rgba_f(1.0, 0.0, 0.0, 0.2);
|
||||||
|
ALLEGRO_COLOR color_text = al_map_rgba_f(1.0, 1.0, 1.0, 0.2);
|
||||||
|
|
||||||
|
al_draw_text(
|
||||||
|
font, color,
|
||||||
|
(data->screen.width / 2) - al_get_text_width(font, "УНИЧТОЖЕНО:") / 2,
|
||||||
|
data->screen.height / 2, 0, "УНИЧТОЖЕНО:");
|
||||||
|
al_draw_textf(
|
||||||
|
font, color_text,
|
||||||
|
(data->screen.width / 2) + al_get_text_width(font, "УНИЧТОЖЕНО:") / 2,
|
||||||
|
data->screen.height / 2, 0, "%d", ship->score);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* File: gameover.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_gameover
|
||||||
|
#define client_gameover
|
||||||
|
|
||||||
|
enum gameover_buttons
|
||||||
|
{
|
||||||
|
BUTTON_GAMEOVER_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
void gameover_handling(CLIENT_DATA* data);
|
||||||
|
void gameover_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void gameover_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void gameover_push_button(CLIENT_DATA* data);
|
||||||
|
static void gameover_draw_statistic(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include <allegro5/allegro.h>
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
#include <allegro5/allegro_native_dialog.h>
|
||||||
|
#include <allegro5/allegro_font.h>
|
||||||
|
#include <allegro5/allegro_ttf.h>
|
||||||
|
#include <allegro5/allegro_image.h>
|
||||||
|
#include <allegro5/allegro_audio.h>
|
||||||
|
#include <allegro5/allegro_acodec.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
void cl_load_allegro_resources()
|
||||||
|
{
|
||||||
|
show_message_error(al_init(), "Failed to initialize Allegro");
|
||||||
|
show_message_error(al_init_primitives_addon(), "Failed to initialize addon primitives");
|
||||||
|
show_message_error(al_init_image_addon(), "Failed to initialize addon image");
|
||||||
|
show_message_error(al_install_keyboard(), "Failed to install keyboard");
|
||||||
|
show_message_error(al_install_mouse(), "Failed to install mouse");
|
||||||
|
show_message_error(al_init_font_addon(), "Failed to initialize addon font");
|
||||||
|
show_message_error(al_init_ttf_addon(), "Failed to initialize addon ttf");
|
||||||
|
show_message_error(al_install_audio(), "Failed to install audio");
|
||||||
|
show_message_error(al_init_acodec_addon(), "Failed to initialize addon acodec");
|
||||||
|
al_reserve_samples(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_RESOURCE* cl_create_resource(CLIENT_RESOURCE* res, CLIENT_PARAMETRS parametrs)
|
||||||
|
{
|
||||||
|
if(!res)
|
||||||
|
{
|
||||||
|
res = (CLIENT_RESOURCE*)malloc(sizeof(CLIENT_RESOURCE));
|
||||||
|
show_message_error(res, "Failed to allocate space for CLIENT_RESOURCE");
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_create_screen(&res->screen, parametrs.scale_factor, parametrs.fullscreen, parametrs.resolution, parametrs.width, parametrs.height, parametrs.FPS, parametrs.num_adapter);
|
||||||
|
cl_create_timer(&res->timer, parametrs.FPS);
|
||||||
|
cl_create_event(&res->event, &res->timer, &res->screen);
|
||||||
|
cl_create_media(&res->media, parametrs.bitmaps_size, parametrs.fonts_size, parametrs.samples_size);
|
||||||
|
cl_create_pairing(&res->pairing, parametrs.pairing_size);
|
||||||
|
cl_create_sound(&res->sound, parametrs.sound_size);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_resource(CLIENT_RESOURCE* res)
|
||||||
|
{
|
||||||
|
cl_destroy_media(&res->media);
|
||||||
|
cl_destroy_event(&res->event);
|
||||||
|
cl_destroy_timer(&res->timer);
|
||||||
|
cl_destroy_screen(&res->screen);
|
||||||
|
cl_destroy_pairing(&res->pairing);
|
||||||
|
cl_destroy_sound(&res->sound);
|
||||||
|
free(res);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* File: common.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.02
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_common
|
||||||
|
#define client_common
|
||||||
|
|
||||||
|
#include "screen.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "event.h"
|
||||||
|
#include "media.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "instance.h"
|
||||||
|
|
||||||
|
typedef struct cl_resource
|
||||||
|
{
|
||||||
|
CLIENT_SCREEN screen;
|
||||||
|
CLIENT_TIMER timer;
|
||||||
|
CLIENT_EVENT event;
|
||||||
|
CLIENT_MEDIA media;
|
||||||
|
CLIENT_PAIRING pairing;
|
||||||
|
CLIENT_SOUND sound;
|
||||||
|
} CLIENT_RESOURCE;
|
||||||
|
|
||||||
|
typedef struct cl_parametrs
|
||||||
|
{
|
||||||
|
float scale_factor;
|
||||||
|
bool fullscreen;
|
||||||
|
bool resolution;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int num_adapter;
|
||||||
|
int FPS;
|
||||||
|
int bitmaps_size;
|
||||||
|
int fonts_size;
|
||||||
|
int samples_size;
|
||||||
|
int pairing_size;
|
||||||
|
int sound_size;
|
||||||
|
char enet_host[20];
|
||||||
|
int enet_port;
|
||||||
|
float effects_gain;
|
||||||
|
float music_gain;
|
||||||
|
} CLIENT_PARAMETRS;
|
||||||
|
|
||||||
|
void cl_load_allegro_resources();
|
||||||
|
CLIENT_RESOURCE* cl_create_resource(CLIENT_RESOURCE* res, CLIENT_PARAMETRS parametrs);
|
||||||
|
void cl_destroy_resource(CLIENT_RESOURCE* res);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include "event.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
CLIENT_EVENT* cl_create_event(CLIENT_EVENT* event, CLIENT_TIMER* timer, CLIENT_SCREEN* screen)
|
||||||
|
{
|
||||||
|
if(!event)
|
||||||
|
{
|
||||||
|
event = (CLIENT_EVENT*)malloc(sizeof(CLIENT_EVENT));
|
||||||
|
show_message_error(event, "Failed to allocate space for CLIENT_EVENT");
|
||||||
|
}
|
||||||
|
|
||||||
|
event->queue = al_create_event_queue();
|
||||||
|
show_message_error(event->queue, "Failed to create Allegro event");
|
||||||
|
|
||||||
|
al_register_event_source(event->queue, al_get_keyboard_event_source());
|
||||||
|
al_register_event_source(event->queue, al_get_mouse_event_source());
|
||||||
|
if(screen)
|
||||||
|
al_register_event_source(event->queue, al_get_display_event_source(screen->display));
|
||||||
|
if(timer)
|
||||||
|
al_register_event_source(event->queue, al_get_timer_event_source(timer->al_timer));
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_event(CLIENT_EVENT* event)
|
||||||
|
{
|
||||||
|
cl_destroy_event(event);
|
||||||
|
free(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
void cl_destroy_event(CLIENT_EVENT* event)
|
||||||
|
{
|
||||||
|
al_destroy_event_queue(event->queue);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* File: event.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.02
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_event
|
||||||
|
#define client_event
|
||||||
|
|
||||||
|
#include <allegro5/allegro5.h>
|
||||||
|
#include "timer.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
typedef struct cl_event
|
||||||
|
{
|
||||||
|
ALLEGRO_EVENT_QUEUE* queue;
|
||||||
|
ALLEGRO_EVENT current;
|
||||||
|
} CLIENT_EVENT;
|
||||||
|
|
||||||
|
CLIENT_EVENT* cl_create_event(CLIENT_EVENT* event, CLIENT_TIMER* timer, CLIENT_SCREEN* screen);
|
||||||
|
void cl_free_event(CLIENT_EVENT* event);
|
||||||
|
void cl_destroy_event(CLIENT_EVENT* event);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "instance.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_SOUND* cl_create_sound(CLIENT_SOUND* sound, int instance_size)
|
||||||
|
{
|
||||||
|
if(!sound)
|
||||||
|
{
|
||||||
|
sound = (CLIENT_SOUND*)malloc(sizeof(CLIENT_SOUND));
|
||||||
|
show_message_error(sound, "Failed to allocate space for CLIENT_SOUND");
|
||||||
|
}
|
||||||
|
|
||||||
|
sound->instance_size = instance_size;
|
||||||
|
sound->current_instance = -1;
|
||||||
|
|
||||||
|
sound->instance = (CLIENT_SAMPLE_INSTANCE**)malloc(sizeof(CLIENT_SAMPLE_INSTANCE*) * instance_size);
|
||||||
|
show_message_error(sound->instance, "Failed to allocate space for CLIENT_SAMPLE_INSTANCE collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < instance_size; i++)
|
||||||
|
{
|
||||||
|
sound->instance[i] = (CLIENT_SAMPLE_INSTANCE*)malloc(sizeof(CLIENT_SAMPLE_INSTANCE));
|
||||||
|
show_message_error(sound->instance[i], "Failed to allocate space for CLIENT_SAMPLE_INSTANCE");
|
||||||
|
|
||||||
|
sound->instance[i]->al_instance = NULL;
|
||||||
|
sound->instance[i]->al_sample = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_sound(CLIENT_SOUND* sound)
|
||||||
|
{
|
||||||
|
cl_destroy_sound(sound);
|
||||||
|
free(sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_sound(CLIENT_SOUND* sound)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sound->instance_size; i++)
|
||||||
|
{
|
||||||
|
if(sound->instance[i]->al_instance)
|
||||||
|
al_destroy_sample_instance(sound->instance[i]->al_instance);
|
||||||
|
free(sound->instance[i]);
|
||||||
|
}
|
||||||
|
free(sound->instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_add_instance(CLIENT_SAMPLE_INSTANCE* instance, ALLEGRO_SAMPLE* sample, ALLEGRO_PLAYMODE playmode, float gain)
|
||||||
|
{
|
||||||
|
instance->playmode = playmode;
|
||||||
|
instance->gain = gain;
|
||||||
|
instance->al_sample = sample;
|
||||||
|
instance->al_instance = al_create_sample_instance(instance->al_sample);
|
||||||
|
al_set_sample_instance_playmode(instance->al_instance, instance->playmode);
|
||||||
|
al_set_sample_instance_gain(instance->al_instance, instance->gain);
|
||||||
|
al_attach_sample_instance_to_mixer(instance->al_instance, al_get_default_mixer());
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* File: instance.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.28
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_instance
|
||||||
|
#define client_instance
|
||||||
|
|
||||||
|
#include <allegro5/allegro_audio.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct cl_sample_instance
|
||||||
|
{
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE* al_instance;
|
||||||
|
ALLEGRO_PLAYMODE playmode;
|
||||||
|
ALLEGRO_SAMPLE* al_sample;
|
||||||
|
float gain;
|
||||||
|
} CLIENT_SAMPLE_INSTANCE;
|
||||||
|
|
||||||
|
typedef struct cl_sound
|
||||||
|
{
|
||||||
|
CLIENT_SAMPLE_INSTANCE** instance;
|
||||||
|
int instance_size;
|
||||||
|
int current_instance;
|
||||||
|
} CLIENT_SOUND;
|
||||||
|
|
||||||
|
CLIENT_SOUND* cl_create_sound(CLIENT_SOUND* sound, int instance_size);
|
||||||
|
void cl_free_sound(CLIENT_SOUND* sound);
|
||||||
|
void cl_destroy_sound(CLIENT_SOUND* sound);
|
||||||
|
|
||||||
|
void cl_add_instance(CLIENT_SAMPLE_INSTANCE* instance, ALLEGRO_SAMPLE* sample, ALLEGRO_PLAYMODE playmode, float gain);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
#include "interface.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_PAIRING* cl_create_pairing(CLIENT_PAIRING* pairing, int interface_size)
|
||||||
|
{
|
||||||
|
if(!pairing)
|
||||||
|
{
|
||||||
|
pairing = (CLIENT_PAIRING*)malloc(sizeof(CLIENT_PAIRING));
|
||||||
|
show_message_error(pairing, "Failed to allocate space for CLIENT_PAIRING");
|
||||||
|
}
|
||||||
|
|
||||||
|
pairing->interface_size = interface_size;
|
||||||
|
|
||||||
|
if(interface_size)
|
||||||
|
{
|
||||||
|
pairing->interface = (CLIENT_INTERFACE**)malloc(sizeof(CLIENT_INTERFACE*) * interface_size);
|
||||||
|
show_message_error(pairing->interface, "Failed to allocate space for CLIENT_INTERFACE collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < interface_size; i++)
|
||||||
|
pairing->interface[i] = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pairing->interface = NULL;
|
||||||
|
|
||||||
|
return pairing;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_INTERFACE* cl_create_interface(int background_size, int button_size, int field_size)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = (CLIENT_INTERFACE*)malloc(sizeof(CLIENT_INTERFACE));
|
||||||
|
show_message_error(interface, "Failed to allocate space for CLIENT_INTERFACE");
|
||||||
|
|
||||||
|
interface->header.al_font = NULL;
|
||||||
|
interface->background_size = background_size;
|
||||||
|
interface->button_size = button_size;
|
||||||
|
interface->field_size = field_size;
|
||||||
|
interface->selected = SELECTED_BUTTON;
|
||||||
|
interface->list.al_font = NULL;
|
||||||
|
|
||||||
|
if(background_size)
|
||||||
|
interface->background = cl_create_background_pages(background_size);
|
||||||
|
else
|
||||||
|
interface->background = NULL;
|
||||||
|
|
||||||
|
if(button_size)
|
||||||
|
interface->button = cl_create_buttons(button_size);
|
||||||
|
else
|
||||||
|
interface->button = NULL;
|
||||||
|
|
||||||
|
if(field_size)
|
||||||
|
interface->field = cl_create_fields(field_size);
|
||||||
|
else
|
||||||
|
interface->field = NULL;
|
||||||
|
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_BACKGROUND_PAGE** cl_create_background_pages(int size)
|
||||||
|
{
|
||||||
|
CLIENT_BACKGROUND_PAGE** background = (CLIENT_BACKGROUND_PAGE**)malloc(sizeof(CLIENT_BACKGROUND_PAGE*) * size);
|
||||||
|
show_message_error(background, "Failed to allocate space for CLIENT_BACKGROUND_PAGE collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
background[i] = (CLIENT_BACKGROUND_PAGE*)malloc(sizeof(CLIENT_BACKGROUND_PAGE));
|
||||||
|
show_message_error(background[i], "Failed to allocate space for CLIENT_BACKGROUND_PAGE");
|
||||||
|
}
|
||||||
|
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_BUTTON** cl_create_buttons(int size)
|
||||||
|
{
|
||||||
|
CLIENT_BUTTON** buttons = (CLIENT_BUTTON**)malloc(sizeof(CLIENT_BUTTON*) * size);
|
||||||
|
show_message_error(buttons, "Failed to allocate space for CLIENT_BUTTON collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
buttons[i] = (CLIENT_BUTTON*)malloc(sizeof(CLIENT_BUTTON));
|
||||||
|
show_message_error(buttons[i], "Failed to allocate space for CLIENT_BUTTON");
|
||||||
|
buttons[i]->al_font = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_FIELD** cl_create_fields(int size)
|
||||||
|
{
|
||||||
|
CLIENT_FIELD** fields = (CLIENT_FIELD**)malloc(sizeof(CLIENT_FIELD*) * size);
|
||||||
|
show_message_error(fields, "Failed to allocate space for CLIENT_FIELD collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
fields[i] = (CLIENT_FIELD*)malloc(sizeof(CLIENT_FIELD));
|
||||||
|
show_message_error(fields[i], "Failed to allocate space for CLIENT_FIELD");
|
||||||
|
fields[i]->al_font = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_change_selected(CLIENT_INTERFACE* interface)
|
||||||
|
{
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_FIELD;
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_FIELD)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_BUTTON;
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
if(interface->field[i]->selected)
|
||||||
|
{
|
||||||
|
interface->field[i]->selected = false;
|
||||||
|
interface->field[i]->enter = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_pairing(CLIENT_PAIRING* pairing)
|
||||||
|
{
|
||||||
|
cl_destroy_pairing(pairing);
|
||||||
|
free(pairing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_pairing(CLIENT_PAIRING* pairing)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < pairing->interface_size; i++)
|
||||||
|
{
|
||||||
|
if(pairing->interface[i])
|
||||||
|
{
|
||||||
|
cl_destroy_interface(pairing->interface[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pairing->interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_destroy_interface(CLIENT_INTERFACE* interface)
|
||||||
|
{
|
||||||
|
if(interface->background_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->background_size; i++)
|
||||||
|
free(interface->background[i]);
|
||||||
|
free(interface->background);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(interface->button_size)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
free(interface->button[i]);
|
||||||
|
free(interface->button);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(interface->field_size)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
free(interface->field[i]);
|
||||||
|
free(interface->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cl_add_interface_header(CLIENT_HEADER* header, ALLEGRO_FONT* font, int x, int y, const char* text)
|
||||||
|
{
|
||||||
|
header->al_font = font;
|
||||||
|
header->size = al_get_text_width(font, text);
|
||||||
|
strncpy(header->text, text, 100);
|
||||||
|
header->x = x;
|
||||||
|
header->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_add_interface_background(CLIENT_BACKGROUND_PAGE* background, CLIENT_BITMAP* bitmap, int dir_x, int dir_y, int vel_x, int vel_y, int x, int y)
|
||||||
|
{
|
||||||
|
background->bitmap = bitmap;
|
||||||
|
background->dir_x = dir_x;
|
||||||
|
background->dir_y = dir_y;
|
||||||
|
background->vel_x = vel_x;
|
||||||
|
background->vel_y = vel_y;
|
||||||
|
background->x = x;
|
||||||
|
background->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_add_interface_button(CLIENT_BUTTON* button, ALLEGRO_FONT* font, const char* text, int t_x, int t_y, int b_sx, int b_sy, int b_dx, int b_dy)
|
||||||
|
{
|
||||||
|
button->al_font = font;
|
||||||
|
strncpy(button->text, text, 100);
|
||||||
|
button->t_size = al_get_text_width(font, text);
|
||||||
|
button->t_x = t_x;
|
||||||
|
button->t_y = t_y;
|
||||||
|
button->selected = false;
|
||||||
|
button->active = false;
|
||||||
|
button->b_sx = b_sx;
|
||||||
|
button->b_sy = b_sy;
|
||||||
|
button->b_dx = b_dx;
|
||||||
|
button->b_dy = b_dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_add_interface_field(CLIENT_FIELD* field, ALLEGRO_FONT* font, int font_height, const char* description, int d_x, int d_y, int f_sx, int f_sy, int f_dx, int f_dy)
|
||||||
|
{
|
||||||
|
field->al_font = font;
|
||||||
|
strncpy(field->description, description, 100);
|
||||||
|
field->char_size = al_get_text_width(font, "_");
|
||||||
|
field->char_number = 0;
|
||||||
|
field->d_x = d_x;
|
||||||
|
field->d_y = d_y;
|
||||||
|
field->f_sx = f_sx;
|
||||||
|
field->f_sy = f_sy - font_height * 0.4;
|
||||||
|
field->f_dx = f_dx + al_get_text_width(font, "_") * 20;
|
||||||
|
field->f_dy = f_dy + font_height * 0.4;
|
||||||
|
field->ft_x = f_sx + al_get_text_width(font, "_") * 0.4;
|
||||||
|
field->ft_y = f_sy;
|
||||||
|
field->selected = false;
|
||||||
|
field->enter = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_add_list_item(CLIENT_LIST_ITEM* item, int sx_item, int sy_item, int dx_item, int dy_item, int x_h, int y_h, int x_status, int y_status, int r_status)
|
||||||
|
{
|
||||||
|
item->sx_item = sx_item;
|
||||||
|
item->sy_item = sy_item;
|
||||||
|
item->dx_item = dx_item;
|
||||||
|
item->dy_item = dy_item;
|
||||||
|
item->x_h = x_h;
|
||||||
|
item->y_h = y_h;
|
||||||
|
item->x_status = x_status;
|
||||||
|
item->y_status = y_status;
|
||||||
|
item->r_status = r_status;
|
||||||
|
item->selected = false;
|
||||||
|
item->active = false;
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* File: interface.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.04
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_interface
|
||||||
|
#define client_interface
|
||||||
|
|
||||||
|
#include <allegro5/allegro_font.h>
|
||||||
|
#include "media.h"
|
||||||
|
|
||||||
|
enum cl_selceted
|
||||||
|
{
|
||||||
|
SELECTED_NONE,
|
||||||
|
SELECTED_BUTTON,
|
||||||
|
SELECTED_FIELD,
|
||||||
|
SELECTED_LIST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct cl_background_page
|
||||||
|
{
|
||||||
|
CLIENT_BITMAP* bitmap;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float vel_x;
|
||||||
|
float vel_y;
|
||||||
|
int dir_x;
|
||||||
|
int dir_y;
|
||||||
|
} CLIENT_BACKGROUND_PAGE;
|
||||||
|
|
||||||
|
typedef struct cl_button
|
||||||
|
{
|
||||||
|
int b_sx;
|
||||||
|
int b_sy;
|
||||||
|
int b_dx;
|
||||||
|
int b_dy;
|
||||||
|
char text[100];
|
||||||
|
int t_size;
|
||||||
|
ALLEGRO_FONT* al_font;
|
||||||
|
int t_x;
|
||||||
|
int t_y;
|
||||||
|
bool selected;
|
||||||
|
bool active;
|
||||||
|
} CLIENT_BUTTON;
|
||||||
|
|
||||||
|
typedef struct cl_field
|
||||||
|
{
|
||||||
|
ALLEGRO_FONT* al_font;
|
||||||
|
char description[100];
|
||||||
|
char field_text[40];
|
||||||
|
int char_size;
|
||||||
|
int char_number;
|
||||||
|
int d_x; // description x position
|
||||||
|
int d_y; // description y position
|
||||||
|
int f_sx; // field sx position
|
||||||
|
int f_sy; // field sy position
|
||||||
|
int f_dx; // field dx position
|
||||||
|
int f_dy; // field dy position
|
||||||
|
int ft_x; // field text x position
|
||||||
|
int ft_y; // field text y position
|
||||||
|
bool selected;
|
||||||
|
bool enter;
|
||||||
|
} CLIENT_FIELD;
|
||||||
|
|
||||||
|
typedef struct cl_header
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
char text[100];
|
||||||
|
int size; // text size
|
||||||
|
ALLEGRO_FONT* al_font;
|
||||||
|
} CLIENT_HEADER;
|
||||||
|
|
||||||
|
typedef struct cl_list_item
|
||||||
|
{
|
||||||
|
int sx_item;
|
||||||
|
int sy_item;
|
||||||
|
int dx_item;
|
||||||
|
int dy_item;
|
||||||
|
int x_h;
|
||||||
|
int y_h;
|
||||||
|
int x_status;
|
||||||
|
int y_status;
|
||||||
|
int r_status;
|
||||||
|
bool selected;
|
||||||
|
bool active;
|
||||||
|
} CLIENT_LIST_ITEM;
|
||||||
|
|
||||||
|
typedef struct cl_list
|
||||||
|
{
|
||||||
|
int sx;
|
||||||
|
int sy;
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
CLIENT_LIST_ITEM item[3];
|
||||||
|
ALLEGRO_FONT* al_font;
|
||||||
|
} CLIENT_LIST;
|
||||||
|
|
||||||
|
typedef struct cl_interface
|
||||||
|
{
|
||||||
|
CLIENT_HEADER header;
|
||||||
|
CLIENT_BACKGROUND_PAGE** background;
|
||||||
|
CLIENT_BUTTON** button;
|
||||||
|
CLIENT_FIELD** field;
|
||||||
|
CLIENT_LIST list;
|
||||||
|
int background_size;
|
||||||
|
int button_size;
|
||||||
|
int field_size;
|
||||||
|
int selected; // selceted current control (none/button/field)
|
||||||
|
} CLIENT_INTERFACE;
|
||||||
|
|
||||||
|
typedef struct cl_pairing
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE** interface;
|
||||||
|
int interface_size;
|
||||||
|
} CLIENT_PAIRING;
|
||||||
|
|
||||||
|
CLIENT_PAIRING* cl_create_pairing(CLIENT_PAIRING* pairing, int interface_size);
|
||||||
|
void cl_free_pairing(CLIENT_PAIRING* pairing);
|
||||||
|
void cl_destroy_pairing(CLIENT_PAIRING* pairing);
|
||||||
|
CLIENT_INTERFACE* cl_create_interface(int background_size, int button_size, int field_size);
|
||||||
|
static void cl_destroy_interface(CLIENT_INTERFACE* interface);
|
||||||
|
|
||||||
|
static CLIENT_BACKGROUND_PAGE** cl_create_background_pages(int size);
|
||||||
|
static CLIENT_BUTTON** cl_create_buttons(int size);
|
||||||
|
static CLIENT_FIELD** cl_create_fields(int size);
|
||||||
|
|
||||||
|
void cl_change_selected(CLIENT_INTERFACE* interface);
|
||||||
|
|
||||||
|
void cl_add_interface_header(CLIENT_HEADER* header, ALLEGRO_FONT* font, int x, int y, const char* text);
|
||||||
|
void cl_add_interface_background(CLIENT_BACKGROUND_PAGE* background, CLIENT_BITMAP* bitmap, int dir_x, int dir_y, int vel_x, int vel_y, int x, int y);
|
||||||
|
void cl_add_interface_button(CLIENT_BUTTON* button, ALLEGRO_FONT* font, const char* text, int t_x, int t_y, int b_sx, int b_sy, int b_dx, int b_dy);
|
||||||
|
void cl_add_interface_field(CLIENT_FIELD* field, ALLEGRO_FONT* font, int font_height, const char* description, int d_x, int d_y, int f_sx, int f_sy, int f_dx, int f_dy);
|
||||||
|
|
||||||
|
// ITEMS
|
||||||
|
void cl_add_list_item(CLIENT_LIST_ITEM* item, int sx_item, int sy_item, int dx_item, int dy_item, int x_h, int y_h, int x_status, int y_status, int r_status);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,141 @@
|
||||||
|
#include "media.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
CLIENT_MEDIA* cl_create_media(CLIENT_MEDIA* media, int size_bitmaps, int size_fonts, int size_samples)
|
||||||
|
{
|
||||||
|
if(!media)
|
||||||
|
{
|
||||||
|
media = (CLIENT_MEDIA*)malloc(sizeof(CLIENT_MEDIA));
|
||||||
|
show_message_error(media, "Failed to allocate space for CLIENT_MEDIA");
|
||||||
|
}
|
||||||
|
|
||||||
|
media->size_bitmaps = size_bitmaps;
|
||||||
|
media->size_fonts = size_fonts;
|
||||||
|
media->size_samples = size_samples;
|
||||||
|
|
||||||
|
media->bitmaps = cl_create_bitmaps(media->size_bitmaps);
|
||||||
|
media->fonts = cl_create_fonts(media->size_fonts);
|
||||||
|
media->samples = cl_create_samples(media->size_samples);
|
||||||
|
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_BITMAP** cl_create_bitmaps(int size)
|
||||||
|
{
|
||||||
|
CLIENT_BITMAP** bitmaps = (CLIENT_BITMAP**)malloc(sizeof(CLIENT_BITMAP*) * size);
|
||||||
|
show_message_error(bitmaps, "Failed to allocate space for CLIENT_BITMAP collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
bitmaps[i] = (CLIENT_BITMAP*)malloc(sizeof(CLIENT_BITMAP));
|
||||||
|
show_message_error(bitmaps[i], "Failed to allocate space for CLIENT_BITMAP");
|
||||||
|
bitmaps[i]->al_bitmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_FONT** cl_create_fonts(int size)
|
||||||
|
{
|
||||||
|
CLIENT_FONT** fonts = (CLIENT_FONT**)malloc(sizeof(CLIENT_FONT*) * size);
|
||||||
|
show_message_error(fonts, "Failed to allocate space for CLIENT_FONT collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
fonts[i] = (CLIENT_FONT*)malloc(sizeof(CLIENT_FONT));
|
||||||
|
show_message_error(fonts[i], "Failed to allocate space for CLIENT_FONT");
|
||||||
|
fonts[i]->al_font = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_SAMPLE** cl_create_samples(int size)
|
||||||
|
{
|
||||||
|
CLIENT_SAMPLE** samples = (CLIENT_SAMPLE**)malloc(sizeof(CLIENT_SAMPLE*) * size);
|
||||||
|
show_message_error(samples, "Failed to allocate space for CLIENT_SAMPLE collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
samples[i] = (CLIENT_SAMPLE*)malloc(sizeof(CLIENT_SAMPLE));
|
||||||
|
show_message_error(samples[i], "Failed to allocate space for CLIENT_SAMPLE");
|
||||||
|
samples[i]->al_sapmle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_media(CLIENT_MEDIA* media)
|
||||||
|
{
|
||||||
|
cl_destroy_media(media);
|
||||||
|
free(media);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_media(CLIENT_MEDIA* media)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < media->size_bitmaps; i++)
|
||||||
|
{
|
||||||
|
if(media->bitmaps[i]->al_bitmap)
|
||||||
|
al_destroy_bitmap(media->bitmaps[i]->al_bitmap);
|
||||||
|
free(media->bitmaps[i]);
|
||||||
|
}
|
||||||
|
free(media->bitmaps);
|
||||||
|
|
||||||
|
for(int i = 0; i < media->size_fonts; i++)
|
||||||
|
{
|
||||||
|
if(media->fonts[i]->al_font)
|
||||||
|
al_destroy_font(media->fonts[i]->al_font);
|
||||||
|
free(media->fonts[i]);
|
||||||
|
}
|
||||||
|
free(media->fonts);
|
||||||
|
|
||||||
|
for(int i = 0; i < media->size_samples; i++)
|
||||||
|
{
|
||||||
|
if(media->samples[i]->al_sapmle)
|
||||||
|
al_destroy_sample(media->samples[i]->al_sapmle);
|
||||||
|
free(media->samples[i]);
|
||||||
|
}
|
||||||
|
free(media->samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_load_bitmap(CLIENT_MEDIA* media, int key_bitmap, const char* path)
|
||||||
|
{
|
||||||
|
if(media->size_bitmaps > key_bitmap && key_bitmap >= 0)
|
||||||
|
{
|
||||||
|
if(!media->bitmaps[key_bitmap]->al_bitmap)
|
||||||
|
{
|
||||||
|
media->bitmaps[key_bitmap]->al_bitmap = al_load_bitmap(path);
|
||||||
|
show_message_error(media->bitmaps[key_bitmap]->al_bitmap, "Failed to load bitmap to collection");
|
||||||
|
media->bitmaps[key_bitmap]->width = al_get_bitmap_width(media->bitmaps[key_bitmap]->al_bitmap);
|
||||||
|
media->bitmaps[key_bitmap]->height = al_get_bitmap_height(media->bitmaps[key_bitmap]->al_bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_load_font(CLIENT_MEDIA* media, int key_font, const char* path, int size_font)
|
||||||
|
{
|
||||||
|
if(media->size_fonts > key_font && key_font >= 0)
|
||||||
|
{
|
||||||
|
if(!media->fonts[key_font]->al_font)
|
||||||
|
{
|
||||||
|
CLIENT_SCREEN screen = cl_get_screen(NULL);
|
||||||
|
|
||||||
|
media->fonts[key_font]->al_font = al_load_font(path, size_font * screen.scale_factor, 0);
|
||||||
|
show_message_error(media->fonts[key_font]->al_font, "Failed to load font to collection");
|
||||||
|
media->fonts[key_font]->size = size_font * screen.scale_factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_load_sample(CLIENT_MEDIA* media, int key_sample, const char* path)
|
||||||
|
{
|
||||||
|
if(media->size_samples > key_sample && key_sample >= 0)
|
||||||
|
{
|
||||||
|
if(!media->samples[key_sample]->al_sapmle)
|
||||||
|
{
|
||||||
|
media->samples[key_sample]->al_sapmle = al_load_sample(path);
|
||||||
|
show_message_error(media->samples[key_sample]->al_sapmle, "Failed to load sample to collection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* File: media.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.02
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_media
|
||||||
|
#define client_media
|
||||||
|
|
||||||
|
#include <allegro5/allegro.h>
|
||||||
|
#include <allegro5/allegro_font.h>
|
||||||
|
#include <allegro5/allegro_audio.h>
|
||||||
|
|
||||||
|
typedef struct cl_bitmap
|
||||||
|
{
|
||||||
|
ALLEGRO_BITMAP* al_bitmap;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} CLIENT_BITMAP;
|
||||||
|
|
||||||
|
typedef struct cl_font
|
||||||
|
{
|
||||||
|
ALLEGRO_FONT* al_font;
|
||||||
|
int size;
|
||||||
|
} CLIENT_FONT;
|
||||||
|
|
||||||
|
typedef struct cl_sample
|
||||||
|
{
|
||||||
|
ALLEGRO_SAMPLE* al_sapmle;
|
||||||
|
} CLIENT_SAMPLE;
|
||||||
|
|
||||||
|
typedef struct cl_media
|
||||||
|
{
|
||||||
|
CLIENT_BITMAP** bitmaps;
|
||||||
|
CLIENT_FONT** fonts;
|
||||||
|
CLIENT_SAMPLE** samples;
|
||||||
|
int size_bitmaps;
|
||||||
|
int size_fonts;
|
||||||
|
int size_samples;
|
||||||
|
} CLIENT_MEDIA;
|
||||||
|
|
||||||
|
CLIENT_MEDIA* cl_create_media(CLIENT_MEDIA* media, int size_bitmaps, int size_fonts, int size_samples);
|
||||||
|
void cl_free_media(CLIENT_MEDIA* media);
|
||||||
|
void cl_destroy_media(CLIENT_MEDIA* media);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Создание коллекции изображений
|
||||||
|
*/
|
||||||
|
static CLIENT_BITMAP** cl_create_bitmaps(int size);
|
||||||
|
/*
|
||||||
|
* Создание коллекции шрифтов
|
||||||
|
*/
|
||||||
|
static CLIENT_FONT** cl_create_fonts(int size);
|
||||||
|
/*
|
||||||
|
* Создание коллекции аудио
|
||||||
|
*/
|
||||||
|
static CLIENT_SAMPLE** cl_create_samples(int size);
|
||||||
|
/*
|
||||||
|
* Загрузка bitmap в коллекцию
|
||||||
|
* keyBitmap - the name of the item enumeration in the array
|
||||||
|
*/
|
||||||
|
void cl_load_bitmap(CLIENT_MEDIA* media, int key_bitmap, const char* path);
|
||||||
|
/*
|
||||||
|
* Загрузка font в коллекцию
|
||||||
|
* keyFont - the name of the item enumeration in the array
|
||||||
|
*/
|
||||||
|
void cl_load_font(CLIENT_MEDIA* media, int key_font, const char* path, int size_font);
|
||||||
|
/*
|
||||||
|
* Загрузка sample в коллекцию
|
||||||
|
* keySample - the name of the item enumeration in the array
|
||||||
|
*/
|
||||||
|
void cl_load_sample(CLIENT_MEDIA* media, int key_sample, const char* path);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <allegro5/allegro_native_dialog.h>
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
void show_message_error(bool result, const char* message)
|
||||||
|
{
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
al_show_native_message_box(NULL, "Сообщение об ошибке", "Произошла ошибка",
|
||||||
|
message, NULL, ALLEGRO_MESSAGEBOX_ERROR);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* File: message.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.05.27
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_message
|
||||||
|
#define client_message
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
/*
|
||||||
|
* error message
|
||||||
|
*/
|
||||||
|
void show_message_error(bool result, const char* message);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,190 @@
|
||||||
|
#include "screen.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_SCREEN* cl_create_screen(CLIENT_SCREEN* screen, float scale_factor, bool fullscreen, bool resolution, int w, int h, int FPS, int num_adapter)
|
||||||
|
{
|
||||||
|
if(!screen)
|
||||||
|
{
|
||||||
|
screen = (CLIENT_SCREEN*)malloc(sizeof(CLIENT_SCREEN));
|
||||||
|
show_message_error(screen, "Failed to allocate space for CLIENT_SCREEN");
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_ADAPTER adapter = cl_get_info_adapter(num_adapter);
|
||||||
|
|
||||||
|
screen->FPS = FPS;
|
||||||
|
screen->monitor_width = adapter.width;
|
||||||
|
screen->monitor_height = adapter.height;
|
||||||
|
screen->display_diagonal = (float)adapter.width / adapter.height;
|
||||||
|
screen->fullscreen = fullscreen;
|
||||||
|
|
||||||
|
if(resolution)
|
||||||
|
{
|
||||||
|
if(w < 640 || h < 400 || ((float)w / h) < 1.0)
|
||||||
|
{
|
||||||
|
screen->width = screen->buffer_width = 640;
|
||||||
|
screen->height = screen->buffer_height = 400;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->width = screen->buffer_width = w;
|
||||||
|
screen->height = screen->buffer_height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->buffer_diagonal = (float)screen->buffer_width / screen->buffer_height;
|
||||||
|
|
||||||
|
if(screen->fullscreen)
|
||||||
|
{
|
||||||
|
if(screen->display_diagonal > screen->buffer_diagonal)
|
||||||
|
{
|
||||||
|
screen->own_diagonal = true;
|
||||||
|
screen->scale_factor = (float)screen->buffer_width / screen->monitor_width;
|
||||||
|
screen->display_width = screen->monitor_width * ((float)screen->buffer_height / screen->monitor_height);
|
||||||
|
screen->display_height = screen->buffer_height;
|
||||||
|
screen->pos_x = (screen->display_width / 2) - (screen->buffer_width / 2);
|
||||||
|
screen->pos_y = 0;
|
||||||
|
}
|
||||||
|
else if(screen->display_diagonal < screen->buffer_diagonal)
|
||||||
|
{
|
||||||
|
screen->own_diagonal = false;
|
||||||
|
screen->scale_factor = (float)screen->buffer_height / screen->monitor_height;
|
||||||
|
screen->display_width = screen->buffer_width;
|
||||||
|
screen->display_height = screen->monitor_height * ((float)screen->buffer_width / screen->monitor_width);
|
||||||
|
screen->pos_x = 0;
|
||||||
|
screen->pos_y = (screen->display_height / 2) - (screen->buffer_height / 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->own_diagonal = true;
|
||||||
|
screen->scale_factor = (float)screen->buffer_width / screen->monitor_width;
|
||||||
|
screen->display_width = screen->buffer_width;
|
||||||
|
screen->display_height = screen->buffer_height;
|
||||||
|
screen->pos_x = 0;
|
||||||
|
screen->pos_y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(screen->display_diagonal >= screen->buffer_diagonal)
|
||||||
|
screen->scale_factor = (float)screen->buffer_width / screen->monitor_width;
|
||||||
|
else if(screen->display_diagonal < screen->buffer_diagonal)
|
||||||
|
screen->scale_factor = (float)screen->buffer_height / screen->monitor_height;
|
||||||
|
|
||||||
|
screen->own_diagonal = true;
|
||||||
|
screen->pos_x = 0;
|
||||||
|
screen->pos_y = 0;
|
||||||
|
screen->display_width = screen->buffer_width;
|
||||||
|
screen->display_height = screen->buffer_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((float)scale_factor >= 0.1 && (float)scale_factor < 1.0)
|
||||||
|
screen->scale_factor = scale_factor;
|
||||||
|
else if((float)scale_factor >= 1.0)
|
||||||
|
{
|
||||||
|
screen->fullscreen = true;
|
||||||
|
screen->scale_factor = 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
screen->scale_factor = 0.5;
|
||||||
|
|
||||||
|
screen->own_diagonal = true;
|
||||||
|
screen->width = screen->buffer_width = screen->display_width = screen->monitor_width * screen->scale_factor;
|
||||||
|
screen->height = screen->buffer_height = screen->display_height = screen->monitor_height * screen->scale_factor;
|
||||||
|
screen->pos_x = 0;
|
||||||
|
screen->pos_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(screen->fullscreen)
|
||||||
|
{
|
||||||
|
screen->scale_factor_x = (float)screen->monitor_width / screen->display_width;
|
||||||
|
screen->scale_factor_y = (float)screen->monitor_height / screen->display_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create allegro display
|
||||||
|
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
|
||||||
|
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
|
||||||
|
|
||||||
|
if(screen->fullscreen)
|
||||||
|
al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
|
||||||
|
|
||||||
|
screen->display = al_create_display(screen->display_width, screen->display_height);
|
||||||
|
show_message_error(screen->display, "Failed to create Allegro display");
|
||||||
|
screen->buffer = al_create_bitmap(screen->buffer_width, screen->buffer_height);
|
||||||
|
show_message_error(screen->buffer, "Failed to create Allegro buffer");
|
||||||
|
|
||||||
|
if(screen->fullscreen)
|
||||||
|
{
|
||||||
|
ALLEGRO_TRANSFORM t;
|
||||||
|
al_identity_transform(&t);
|
||||||
|
al_scale_transform(&t, screen->scale_factor_x, screen->scale_factor_y);
|
||||||
|
al_use_transform(&t);
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_get_screen(screen);
|
||||||
|
|
||||||
|
return screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_ADAPTER cl_get_info_adapter(int num_adapter)
|
||||||
|
{
|
||||||
|
CLIENT_ADAPTER adapter;
|
||||||
|
const int num_monitor = al_get_num_video_adapters();
|
||||||
|
ALLEGRO_MONITOR_INFO m_i;
|
||||||
|
int cur_adapter;
|
||||||
|
|
||||||
|
show_message_error(num_monitor, "Could not find connected monitors");
|
||||||
|
|
||||||
|
if(num_adapter != -1 && num_adapter <= num_monitor - 1)
|
||||||
|
cur_adapter = num_adapter;
|
||||||
|
else
|
||||||
|
cur_adapter = 0;
|
||||||
|
|
||||||
|
al_get_monitor_info(cur_adapter, &m_i);
|
||||||
|
|
||||||
|
adapter.width = m_i.x2 - m_i.x1;
|
||||||
|
adapter.height = m_i.y2 - m_i.y1;
|
||||||
|
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_screen(CLIENT_SCREEN* screen)
|
||||||
|
{
|
||||||
|
cl_destroy_screen(screen);
|
||||||
|
free(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_screen(CLIENT_SCREEN* screen)
|
||||||
|
{
|
||||||
|
al_destroy_bitmap(screen->buffer);
|
||||||
|
al_destroy_display(screen->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_SCREEN cl_get_screen(CLIENT_SCREEN* screen)
|
||||||
|
{
|
||||||
|
static CLIENT_SCREEN screen_info;
|
||||||
|
|
||||||
|
if(screen)
|
||||||
|
{
|
||||||
|
screen_info = *screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return screen_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_pre_draw()
|
||||||
|
{
|
||||||
|
CLIENT_SCREEN screen = cl_get_screen(NULL);
|
||||||
|
|
||||||
|
al_set_target_bitmap(screen.buffer);
|
||||||
|
al_clear_to_color(al_map_rgb(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_post_draw()
|
||||||
|
{
|
||||||
|
CLIENT_SCREEN screen = cl_get_screen(NULL);
|
||||||
|
|
||||||
|
al_set_target_backbuffer(screen.display);
|
||||||
|
al_draw_scaled_bitmap(screen.buffer, 0, 0, screen.buffer_width, screen.buffer_height, screen.pos_x, screen.pos_y, screen.buffer_width, screen.buffer_height, 0);
|
||||||
|
al_flip_display();
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* File: screen.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 27 мая 2020 г., 17:17
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_screen
|
||||||
|
#define client_screen
|
||||||
|
|
||||||
|
#include <allegro5/allegro5.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct cl_screen
|
||||||
|
{
|
||||||
|
ALLEGRO_DISPLAY* display;
|
||||||
|
ALLEGRO_BITMAP* buffer;
|
||||||
|
int monitor_width;
|
||||||
|
int monitor_height;
|
||||||
|
int display_width;
|
||||||
|
int display_height;
|
||||||
|
int buffer_width;
|
||||||
|
int buffer_height;
|
||||||
|
int width; // main width (== buffer width)
|
||||||
|
int height; // main height (== buffer height)
|
||||||
|
float display_diagonal;
|
||||||
|
float buffer_diagonal;
|
||||||
|
bool own_diagonal; // use own diagonal (if own diagonal >)
|
||||||
|
float scale_factor;
|
||||||
|
float scale_factor_x;
|
||||||
|
float scale_factor_y;
|
||||||
|
int FPS;
|
||||||
|
bool fullscreen;
|
||||||
|
int pos_x; // display output buffer position x
|
||||||
|
int pos_y; // display output buffer position y
|
||||||
|
} CLIENT_SCREEN;
|
||||||
|
|
||||||
|
typedef struct cl_adapter
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} CLIENT_ADAPTER;
|
||||||
|
|
||||||
|
CLIENT_SCREEN* cl_create_screen(CLIENT_SCREEN* screen, float scale_factor, bool fullscreen, bool resolution, int w, int h, int FPS, int num_adapter);
|
||||||
|
|
||||||
|
static CLIENT_ADAPTER cl_get_info_adapter(int num_adapter);
|
||||||
|
|
||||||
|
void cl_free_screen(CLIENT_SCREEN* screen);
|
||||||
|
void cl_destroy_screen(CLIENT_SCREEN* screen);
|
||||||
|
|
||||||
|
void cl_pre_draw();
|
||||||
|
|
||||||
|
void cl_post_draw();
|
||||||
|
|
||||||
|
CLIENT_SCREEN cl_get_screen(CLIENT_SCREEN* screen);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "timer.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_TIMER* cl_create_timer(CLIENT_TIMER* timer, int FPS)
|
||||||
|
{
|
||||||
|
if(!timer)
|
||||||
|
{
|
||||||
|
timer = (CLIENT_TIMER*)malloc(sizeof(CLIENT_TIMER));
|
||||||
|
show_message_error(timer, "Failed to allocate space for CLIENT_TIMER");
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->al_timer = al_create_timer(1.0 / FPS);
|
||||||
|
show_message_error(timer->al_timer, "Failed to create Allegro timer");
|
||||||
|
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_timer(CLIENT_TIMER* timer)
|
||||||
|
{
|
||||||
|
cl_destroy_timer(timer);
|
||||||
|
free(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_timer(CLIENT_TIMER* timer)
|
||||||
|
{
|
||||||
|
al_destroy_timer(timer->al_timer);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* File: timer.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.02
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_timer
|
||||||
|
#define client_timer
|
||||||
|
|
||||||
|
#include <allegro5/allegro5.h>
|
||||||
|
|
||||||
|
typedef struct cl_timer
|
||||||
|
{
|
||||||
|
ALLEGRO_TIMER* al_timer;
|
||||||
|
float time;
|
||||||
|
} CLIENT_TIMER;
|
||||||
|
|
||||||
|
CLIENT_TIMER* cl_create_timer(CLIENT_TIMER* timer, int FPS);
|
||||||
|
|
||||||
|
void cl_free_timer(CLIENT_TIMER* timer);
|
||||||
|
void cl_destroy_timer(CLIENT_TIMER* timer);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
cl_load_allegro_resources();
|
||||||
|
|
||||||
|
CLIENT_PARAMETRS parametrs =
|
||||||
|
{
|
||||||
|
// screen
|
||||||
|
.num_adapter = 0,
|
||||||
|
.scale_factor = 0.5,
|
||||||
|
.fullscreen = false,
|
||||||
|
.resolution = true,
|
||||||
|
.width = 1280,
|
||||||
|
.height = 540,
|
||||||
|
.FPS = 60,
|
||||||
|
// media
|
||||||
|
.bitmaps_size = 8,
|
||||||
|
.fonts_size = 4,
|
||||||
|
.samples_size = 6,
|
||||||
|
// interface
|
||||||
|
.pairing_size = 13,
|
||||||
|
.sound_size = 2,
|
||||||
|
// network
|
||||||
|
.enet_port = 9234,
|
||||||
|
.enet_host = "127.0.0.1",
|
||||||
|
// settings
|
||||||
|
.effects_gain = 0.1,
|
||||||
|
.music_gain = 0.1
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIENT_DATA* data = cl_create_data(NULL, parametrs);
|
||||||
|
|
||||||
|
cl_init_interfaces(&data->pairing);
|
||||||
|
cl_load_media(&data->media);
|
||||||
|
cl_init_media(data);
|
||||||
|
|
||||||
|
al_start_timer(data->timer.al_timer);
|
||||||
|
data->timer.time = al_current_time();
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
|
||||||
|
while(!data->done)
|
||||||
|
{
|
||||||
|
al_wait_for_event(data->event.queue, &data->event.current);
|
||||||
|
|
||||||
|
if(data->state == MENU)
|
||||||
|
menu_handling(data);
|
||||||
|
if(data->state == AUTORS)
|
||||||
|
autors_handling(data);
|
||||||
|
if(data->state == SINGLE)
|
||||||
|
single_handling(data);
|
||||||
|
if(data->state == NETWORKMODE)
|
||||||
|
networkmode_handling(data);
|
||||||
|
if(data->state == NETWORKCREATE)
|
||||||
|
networkcreate_handling(data);
|
||||||
|
if(data->state == NETWORKJOIN)
|
||||||
|
networkjoin_handling(data);
|
||||||
|
if(data->state == NETWORKPARTY)
|
||||||
|
networkparty_handling(data);
|
||||||
|
if(data->state == NETWORKLIST)
|
||||||
|
networklist_handling(data);
|
||||||
|
if(data->state == NETWORKGAME)
|
||||||
|
networkgame_handling(data);
|
||||||
|
if(data->state == NETWORKOUT)
|
||||||
|
networkout_handling(data);
|
||||||
|
if(data->state == PAUSE)
|
||||||
|
pause_handling(data);
|
||||||
|
if(data->state == GAMEOVER)
|
||||||
|
gameover_handling(data);
|
||||||
|
|
||||||
|
if(data->render && al_is_event_queue_empty(data->event.queue))
|
||||||
|
{
|
||||||
|
data->render = false;
|
||||||
|
cl_pre_draw();
|
||||||
|
|
||||||
|
if(data->state == MENU)
|
||||||
|
menu_draw(data);
|
||||||
|
if(data->state == AUTORS)
|
||||||
|
autors_draw(data);
|
||||||
|
if(data->state == SINGLE)
|
||||||
|
single_draw(data);
|
||||||
|
if(data->state == NETWORKMODE)
|
||||||
|
networkmode_draw(data);
|
||||||
|
if(data->state == NETWORKCREATE)
|
||||||
|
networkcreate_draw(data);
|
||||||
|
if(data->state == NETWORKJOIN)
|
||||||
|
networkjoin_draw(data);
|
||||||
|
if(data->state == NETWORKPARTY)
|
||||||
|
networkparty_draw(data);
|
||||||
|
if(data->state == NETWORKLIST)
|
||||||
|
networklist_draw(data);
|
||||||
|
if(data->state == NETWORKGAME)
|
||||||
|
networkgame_draw(data);
|
||||||
|
if(data->state == NETWORKOUT)
|
||||||
|
networkout_draw(data);
|
||||||
|
if(data->state == PAUSE)
|
||||||
|
pause_draw(data);
|
||||||
|
if(data->state == GAMEOVER)
|
||||||
|
gameover_draw(data);
|
||||||
|
|
||||||
|
cl_post_draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_destroy_data(data);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "menu.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void menu_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
data->done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
menu_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
menu_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
menu_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void menu_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void menu_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[MENU]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[MENU]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 2)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 2) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 2) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_MENU_SINGLE:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
al_hide_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, SINGLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON_MENU_NETWORK:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON_MENU_SETTINGS:
|
||||||
|
break;
|
||||||
|
case BUTTON_MENU_AUTORS:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, AUTORS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON_MENU_OUT:
|
||||||
|
data->done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* File: menu.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_menu
|
||||||
|
#define client_menu
|
||||||
|
|
||||||
|
enum menu_buttons
|
||||||
|
{
|
||||||
|
BUTTON_MENU_SINGLE, // single play
|
||||||
|
BUTTON_MENU_NETWORK, // network play
|
||||||
|
BUTTON_MENU_SETTINGS, // settings
|
||||||
|
BUTTON_MENU_AUTORS, // autors
|
||||||
|
BUTTON_MENU_OUT // output
|
||||||
|
};
|
||||||
|
|
||||||
|
void menu_handling(CLIENT_DATA* data);
|
||||||
|
void menu_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void menu_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void menu_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_ENET* cl_create_enet(CLIENT_ENET* enet)
|
||||||
|
{
|
||||||
|
if(!enet)
|
||||||
|
{
|
||||||
|
enet = (CLIENT_ENET*)malloc(sizeof(CLIENT_ENET));
|
||||||
|
show_message_error(enet, "Failed to allocate space for CLIENT_ENET");
|
||||||
|
}
|
||||||
|
|
||||||
|
show_message_error(enet_initialize() == 0, "Failed to allocate space for CLIENT_ENET");
|
||||||
|
|
||||||
|
int port = enet->port;
|
||||||
|
char host[20];
|
||||||
|
strncpy(host, enet->host, 20);
|
||||||
|
|
||||||
|
enet->client = enet_host_create(NULL, 1, 2, 0, 0);
|
||||||
|
show_message_error(enet->client, "Failed to client host create");
|
||||||
|
|
||||||
|
enet_address_set_host(&enet->address, host);
|
||||||
|
enet->address.port = port;
|
||||||
|
|
||||||
|
enet->server = enet_host_connect(enet->client, &enet->address, 2, 0);
|
||||||
|
show_message_error(enet->server, "Failed to server connect");
|
||||||
|
|
||||||
|
if (enet_host_service(enet->client, &enet->event, 5000) > 0 && enet->event.type == ENET_EVENT_TYPE_CONNECT)
|
||||||
|
{
|
||||||
|
enet->connect = true;
|
||||||
|
printf("Клиент: присоединён к серверу %x:%hu\n", enet->event.peer->address.host, enet->event.peer->address.port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enet->connect = false;
|
||||||
|
puts("Клиент: не удалось присоединиться к серверу");
|
||||||
|
enet_peer_reset(enet->server);
|
||||||
|
cl_destroy_enet(enet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return enet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_enet(CLIENT_ENET* enet)
|
||||||
|
{
|
||||||
|
cl_destroy_enet(enet);
|
||||||
|
free(enet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_enet(CLIENT_ENET* enet)
|
||||||
|
{
|
||||||
|
enet_host_destroy(enet->client);
|
||||||
|
enet_deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_disconnect_enet(CLIENT_ENET* enet)
|
||||||
|
{
|
||||||
|
enet_peer_disconnect(enet->server, 0);
|
||||||
|
|
||||||
|
ENetEvent event;
|
||||||
|
|
||||||
|
while (enet_host_service (enet->client, &event, 3000) > 0)
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
break;
|
||||||
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
puts("Клиент: успешное отсоединение");
|
||||||
|
return;
|
||||||
|
case ENET_EVENT_TYPE_NONE:
|
||||||
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_peer_reset(enet->server);
|
||||||
|
|
||||||
|
enet->connect = false;
|
||||||
|
cl_destroy_enet(enet);
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* File: network.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_network
|
||||||
|
#define client_network
|
||||||
|
|
||||||
|
#include <enet/enet.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef enum srv_state
|
||||||
|
{
|
||||||
|
STATE_NONE,
|
||||||
|
STATE_LIST,
|
||||||
|
STATE_PARTY,
|
||||||
|
STATE_GAME,
|
||||||
|
STATE_DISCONNECT
|
||||||
|
} SERVER_STATE;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct cl_user_command
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
} SERVER_USER_COMMAND;
|
||||||
|
|
||||||
|
typedef struct cl_user
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char nickname[40];
|
||||||
|
bool is_ready;
|
||||||
|
SERVER_USER_COMMAND command;
|
||||||
|
} CLIENT_USER;
|
||||||
|
|
||||||
|
typedef struct cl_gamedata
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char game_name[40];
|
||||||
|
int count_connected;
|
||||||
|
} CLIENT_GAME_DATA;
|
||||||
|
|
||||||
|
typedef struct cl_game_command
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
bool send;
|
||||||
|
} CLIENT_GAME_COMMAND;
|
||||||
|
|
||||||
|
typedef struct cl_network
|
||||||
|
{
|
||||||
|
int game_id;
|
||||||
|
int user_id;
|
||||||
|
char game_name[40];
|
||||||
|
CLIENT_USER users[3];
|
||||||
|
CLIENT_GAME_DATA games[3];
|
||||||
|
int user_size;
|
||||||
|
int count_connected;
|
||||||
|
int count_game;
|
||||||
|
bool game_started;
|
||||||
|
bool active;
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
CLIENT_GAME_COMMAND command;
|
||||||
|
} CLIENT_NETWORK;
|
||||||
|
|
||||||
|
typedef struct cl_message_none
|
||||||
|
{
|
||||||
|
int display_width;
|
||||||
|
int display_height;
|
||||||
|
float scale_factor;
|
||||||
|
SERVER_STATE state;
|
||||||
|
char game_name[40];
|
||||||
|
char nickname[40];
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
} CLIENT_MESSAGE_NONE;
|
||||||
|
|
||||||
|
typedef struct cl_message_party
|
||||||
|
{
|
||||||
|
int game_id;
|
||||||
|
int user_id;
|
||||||
|
CLIENT_USER users[3];
|
||||||
|
char game_name[40];
|
||||||
|
int count_connected;
|
||||||
|
bool game_started;
|
||||||
|
bool active;
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} CLIENT_MESSAGE_PARTY;
|
||||||
|
|
||||||
|
typedef struct cl_message_list
|
||||||
|
{
|
||||||
|
CLIENT_GAME_DATA games[3];
|
||||||
|
SERVER_STATE state;
|
||||||
|
int count_game;
|
||||||
|
} CLIENT_MESSAGE_LIST;
|
||||||
|
|
||||||
|
typedef struct cl_message_joingame
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} CLIENT_MESSAGE_JOINGAME;
|
||||||
|
|
||||||
|
typedef struct cl_message_sendparty
|
||||||
|
{
|
||||||
|
SERVER_STATE state;
|
||||||
|
bool is_creator;
|
||||||
|
bool is_ready;
|
||||||
|
bool kick_user;
|
||||||
|
int user_id;
|
||||||
|
} CLIENT_MESSAGE_SENDPARTY;
|
||||||
|
|
||||||
|
typedef struct cl_message_game
|
||||||
|
{
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
bool fire;
|
||||||
|
SERVER_STATE state;
|
||||||
|
} CLIENT_MESSAGE_GAME;
|
||||||
|
|
||||||
|
// GAME
|
||||||
|
|
||||||
|
typedef struct cl_update_ship
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
int lives;
|
||||||
|
int score;
|
||||||
|
bool active;
|
||||||
|
} CLIENT_UPDATE_SHIP;
|
||||||
|
|
||||||
|
typedef struct cl_update_bullet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
bool active;
|
||||||
|
} CLIENT_UPDATE_BULLET;
|
||||||
|
|
||||||
|
typedef struct cl_update_comet
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
} CLIENT_UPDATE_COMET;
|
||||||
|
|
||||||
|
typedef struct cl_update_explosion
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
} CLIENT_UPDATE_EXPLOSION;
|
||||||
|
|
||||||
|
typedef struct cl_message_update
|
||||||
|
{
|
||||||
|
CLIENT_UPDATE_SHIP ship[3];
|
||||||
|
CLIENT_UPDATE_BULLET bullet[15];
|
||||||
|
CLIENT_UPDATE_COMET comet[15];
|
||||||
|
CLIENT_UPDATE_EXPLOSION explosion[15];
|
||||||
|
} CLIENT_MESSAGE_UPDATE;
|
||||||
|
|
||||||
|
typedef struct cl_enet
|
||||||
|
{
|
||||||
|
ENetHost* client;
|
||||||
|
ENetPeer* server;
|
||||||
|
ENetEvent event;
|
||||||
|
ENetAddress address;
|
||||||
|
bool connect;
|
||||||
|
int port;
|
||||||
|
char host[20];
|
||||||
|
} CLIENT_ENET;
|
||||||
|
|
||||||
|
CLIENT_ENET* cl_create_enet(CLIENT_ENET* enet);
|
||||||
|
void cl_free_enet(CLIENT_ENET* enet);
|
||||||
|
void cl_destroy_enet(CLIENT_ENET* enet);
|
||||||
|
void cl_disconnect_enet(CLIENT_ENET* enet);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkcreate.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkcreate_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networkcreate_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkcreate_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_TAB:
|
||||||
|
networkcreate_change_selected(data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cl_print_field(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
cl_update_field(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networkcreate_push_button(data);
|
||||||
|
cl_enter_field(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkcreate_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
|
||||||
|
cl_draw_field(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
/************************************************************
|
||||||
|
* FIELD
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkcreate_init_field(CLIENT_DATA* data, int key_field, int key_font, const char* description)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKCREATE]->field_size > key_field)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_field(
|
||||||
|
data->pairing.interface[NETWORKCREATE]->field[key_field],
|
||||||
|
font->al_font, font->size, description,
|
||||||
|
(data->screen.width / 2) - al_get_text_width(font->al_font, description),
|
||||||
|
(block_size * (key_field + 3) - font->size / 2),
|
||||||
|
(data->screen.width / 2),
|
||||||
|
(block_size * (key_field + 3) - font->size / 2),
|
||||||
|
(data->screen.width / 2),
|
||||||
|
(block_size * (key_field + 3) + font->size / 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkcreate_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKCREATE]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKCREATE]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 5)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 5) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 5) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkcreate_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKCREATE_CREATE:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
if(networkcreate_check_field(data))
|
||||||
|
cl_change_state(data, NETWORKPARTY);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKCREATE_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_FIELD)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
if(interface->field[i]->selected)
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case FIELD_NETWORKCREATE_NICKNAME:
|
||||||
|
interface->field[i]->enter = true;
|
||||||
|
break;
|
||||||
|
case FIELD_NETWORKCREATE_GAMENAME:
|
||||||
|
interface->field[i]->enter = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkcreate_change_selected(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_change_selected(data->pairing.interface[data->state]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool networkcreate_check_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
int field_size = interface->field_size;
|
||||||
|
int field_filled_size = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < field_size; i++)
|
||||||
|
if(interface->field[i]->char_number > 0)
|
||||||
|
field_filled_size++;
|
||||||
|
|
||||||
|
return field_size == field_filled_size;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* File: network_create.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_networkcreate
|
||||||
|
#define client_networkcreate
|
||||||
|
|
||||||
|
enum networkcreate_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKCREATE_CREATE,
|
||||||
|
BUTTON_NETWORKCREATE_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum networkcreate_field
|
||||||
|
{
|
||||||
|
FIELD_NETWORKCREATE_NICKNAME,
|
||||||
|
FIELD_NETWORKCREATE_GAMENAME
|
||||||
|
};
|
||||||
|
|
||||||
|
void networkcreate_handling(CLIENT_DATA* data);
|
||||||
|
void networkcreate_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void networkcreate_init_field(CLIENT_DATA* data, int key_field, int key_font, const char* description);
|
||||||
|
void networkcreate_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void networkcreate_push_button(CLIENT_DATA* data);
|
||||||
|
static void networkcreate_change_selected(CLIENT_DATA* data);
|
||||||
|
static bool networkcreate_check_field(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,571 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkgame.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkgame_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
al_show_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, NETWORKOUT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
// cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
// cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
// networkparty_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkgame_fire_bullet(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_TAB:
|
||||||
|
// networkparty_change_selected(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
// cl_update_list(data);
|
||||||
|
// cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
// networkparty_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
if(data->keys[UP])
|
||||||
|
networkgame_move_ship_up(data);
|
||||||
|
else if(data->keys[DOWN])
|
||||||
|
networkgame_move_ship_down(data);
|
||||||
|
else
|
||||||
|
networkgame_reset_ship_animation(data, 1);
|
||||||
|
|
||||||
|
if(data->keys[LEFT])
|
||||||
|
networkgame_move_ship_left(data);
|
||||||
|
else if(data->keys[RIGHT])
|
||||||
|
networkgame_move_ship_right(data);
|
||||||
|
else
|
||||||
|
networkgame_reset_ship_animation(data, 2);
|
||||||
|
|
||||||
|
networkgame_update_explosions(data);
|
||||||
|
networkgame_update_comet(data);
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG3);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
|
||||||
|
networkgame_enet_receive(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkgame_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG3);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
|
||||||
|
networkgame_draw_ship(data);
|
||||||
|
networkgame_draw_bullet(data);
|
||||||
|
networkgame_draw_comet(data);
|
||||||
|
networkgame_draw_explosions(data);
|
||||||
|
networkgame_draw_statistic(data);
|
||||||
|
|
||||||
|
networkgame_send_move_ship(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkgame_create_objects(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
int iterator = 0;
|
||||||
|
|
||||||
|
cl_create_objects(objects, data->network.count_connected, 5 * data->network.count_connected, 15, 5 * data->network.count_connected);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->ship_size; i++)
|
||||||
|
{
|
||||||
|
cl_init_ships(objects, iterator, data->network.users[i].id, 3, 1, 1, 10, 12, 0, 0, 50, 41, 46, data->media.bitmaps[SHIP_R + i]->al_bitmap, 3, 3, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
for(int j = iterator++ * 5; j < iterator * 5; j++)
|
||||||
|
cl_init_bullets(objects, j, data->network.users[i].id, 10, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
cl_init_comets(objects, i, 0, 21, rand() % 2 ? 1 : -1, 35, 35, 0, 0, 2, 96, 96, data->media.bitmaps[COMET]->al_bitmap, 143, 5, 0, 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
cl_init_explosions(objects, i, 8, 1, 0, 0, 1, 128, 128, data->media.bitmaps[EXPLOSION]->al_bitmap, 31, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void networkgame_enet_receive(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
ENetEvent event;
|
||||||
|
CLIENT_MESSAGE_UPDATE* message;
|
||||||
|
|
||||||
|
while(enet_host_service(data->enet.client, &event, 0) > 0)
|
||||||
|
if(event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||||
|
{
|
||||||
|
message = (CLIENT_MESSAGE_UPDATE*)event.packet->data;
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
for(int j = 0; j < 3; j++)
|
||||||
|
if(ship->ID == message->ship[j].ID)
|
||||||
|
{
|
||||||
|
ship->x = message->ship[j].x;
|
||||||
|
ship->y = message->ship[j].y;
|
||||||
|
ship->lives = message->ship[j].lives;
|
||||||
|
ship->score = message->ship[j].score;
|
||||||
|
ship->active = message->ship[j].active;
|
||||||
|
|
||||||
|
for(int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
CLIENT_USER* user = &data->network.users[k];
|
||||||
|
|
||||||
|
if(user->id == ship->ID)
|
||||||
|
{
|
||||||
|
user->command.dx = message->ship[j].dx;
|
||||||
|
user->command.dy = message->ship[j].dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.bullet_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_BULLET* bullet = data->objects.bullets[i];
|
||||||
|
|
||||||
|
if(message->bullet[i].live && !bullet->live)
|
||||||
|
cl_play_sound(data, SAMPLE_SHOT);
|
||||||
|
|
||||||
|
bullet->ID = message->bullet[i].ID;
|
||||||
|
bullet->active = message->bullet[i].active;
|
||||||
|
bullet->live = message->bullet[i].live;
|
||||||
|
bullet->x = message->bullet[i].x;
|
||||||
|
bullet->y = message->bullet[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.comet_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_COMET* comet = data->objects.comets[i];
|
||||||
|
|
||||||
|
comet->live = message->comet[i].live;
|
||||||
|
comet->x = message->comet[i].x;
|
||||||
|
comet->y = message->comet[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.explosion_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_EXPLOSION* explosion = data->objects.explosions[i];
|
||||||
|
|
||||||
|
if(message->explosion[i].live)
|
||||||
|
{
|
||||||
|
if(message->explosion[i].live && !explosion->live)
|
||||||
|
cl_play_sound(data, SAMPLE_BOOM);
|
||||||
|
|
||||||
|
explosion->live = message->explosion[i].live;
|
||||||
|
explosion->x = message->explosion[i].x;
|
||||||
|
explosion->y = message->explosion[i].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_send_move_ship(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->network.command.send)
|
||||||
|
{
|
||||||
|
CLIENT_GAME_COMMAND command = data->network.command;
|
||||||
|
|
||||||
|
command.send = false;
|
||||||
|
|
||||||
|
ENetPacket *packet;
|
||||||
|
CLIENT_MESSAGE_GAME message;
|
||||||
|
|
||||||
|
message.dx = command.dx;
|
||||||
|
message.dy = command.dy;
|
||||||
|
message.fire = command.fire;
|
||||||
|
message.state = STATE_GAME;
|
||||||
|
|
||||||
|
data->network.command.fire = false;
|
||||||
|
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkgame_draw_ship(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(!ship->active) continue;
|
||||||
|
|
||||||
|
for(int j = 0; j < data->objects.ship_size; j++)
|
||||||
|
{
|
||||||
|
CLIENT_USER* user = &data->network.users[j];
|
||||||
|
|
||||||
|
if(user->id == ship->ID)
|
||||||
|
{
|
||||||
|
if(user->command.dy == -1)
|
||||||
|
ship->animation_row = 0;
|
||||||
|
else if(user->command.dy == 1)
|
||||||
|
ship->animation_row = 2;
|
||||||
|
else
|
||||||
|
ship->animation_row = 1;
|
||||||
|
|
||||||
|
if(user->command.dx == -1)
|
||||||
|
ship->cur_frame = 2;
|
||||||
|
else if(user->command.dx == 1)
|
||||||
|
ship->cur_frame = 1;
|
||||||
|
else
|
||||||
|
ship->cur_frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fx = (ship->cur_frame % ship->animation_columns) * ship->frame_width;
|
||||||
|
int fy = ship->animation_row * ship->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(ship->image, fx, fy, ship->frame_width, ship->frame_height,
|
||||||
|
ship->x - ship->frame_width / 2, ship->y - ship->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_move_ship_up(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id)
|
||||||
|
{
|
||||||
|
ship->animation_row = 0;
|
||||||
|
data->network.command.dy = -1;
|
||||||
|
data->network.command.send = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_move_ship_down(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id)
|
||||||
|
{
|
||||||
|
ship->animation_row = 2;
|
||||||
|
data->network.command.dy = 1;
|
||||||
|
data->network.command.send = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_move_ship_left(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id)
|
||||||
|
{
|
||||||
|
ship->cur_frame = 2;
|
||||||
|
data->network.command.dx = -1;
|
||||||
|
data->network.command.send = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_move_ship_right(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id)
|
||||||
|
{
|
||||||
|
ship->cur_frame = 1;
|
||||||
|
data->network.command.dx = 1;
|
||||||
|
data->network.command.send = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_reset_ship_animation(CLIENT_DATA* data, int position)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id)
|
||||||
|
{
|
||||||
|
if(position == 1)
|
||||||
|
{
|
||||||
|
ship->animation_row = 1;
|
||||||
|
data->network.command.dy = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ship->cur_frame = 0;
|
||||||
|
data->network.command.dx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->network.command.send = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool networkgame_dead_ship(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
return data->objects.ships[0]->lives <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkgame_fire_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
|
||||||
|
if(ship->ID == data->network.user_id && ship->active)
|
||||||
|
data->network.command.fire = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkgame_draw_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_BULLET* bullet = objects->bullets[i];
|
||||||
|
|
||||||
|
if(bullet->live)
|
||||||
|
al_draw_filled_circle(bullet->x, bullet->y, 2, al_map_rgb(255, 255, 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkgame_draw_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_COMET* comet = objects->comets[i];
|
||||||
|
|
||||||
|
if(comet->live)
|
||||||
|
{
|
||||||
|
int fx = (comet->cur_frame % comet->animation_columns) * comet->frame_width;
|
||||||
|
int fy = (comet->cur_frame / comet->animation_columns) * comet->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(comet->image, fx, fy, comet->frame_width, comet->frame_height,
|
||||||
|
comet->x - comet->frame_width / 2, comet->y - comet->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void networkgame_update_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_COMET* comet = objects->comets[i];
|
||||||
|
|
||||||
|
if(comet->live)
|
||||||
|
{
|
||||||
|
if(++comet->frame_count >= comet->frame_delay)
|
||||||
|
{
|
||||||
|
comet->cur_frame += comet->animation_direction;
|
||||||
|
if(comet->cur_frame >= comet->max_frame)
|
||||||
|
comet->cur_frame = 0;
|
||||||
|
else if(comet->cur_frame <= 0)
|
||||||
|
comet->cur_frame = comet->max_frame - 1;
|
||||||
|
|
||||||
|
comet->frame_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSION
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkgame_draw_explosions(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_EXPLOSION* explosion = objects->explosions[i];
|
||||||
|
|
||||||
|
if(explosion->live)
|
||||||
|
{
|
||||||
|
int fx = (explosion->cur_frame % explosion->animation_columns) * explosion->frame_width;
|
||||||
|
int fy = (explosion->cur_frame / explosion->animation_columns) * explosion->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(explosion->image, fx, fy, explosion->frame_width, explosion->frame_height,
|
||||||
|
explosion->x - explosion->frame_width / 2, explosion->y - explosion->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void networkgame_update_explosions(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_EXPLOSION* explosion = objects->explosions[i];
|
||||||
|
|
||||||
|
if(explosion->live)
|
||||||
|
if(++explosion->frame_count >= explosion->frame_delay)
|
||||||
|
{
|
||||||
|
explosion->cur_frame += explosion->animation_direction;
|
||||||
|
if(explosion->cur_frame >= explosion->max_frame)
|
||||||
|
{
|
||||||
|
explosion->cur_frame = 0;
|
||||||
|
explosion->live = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
explosion->frame_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* STATISTIC
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkgame_draw_statistic(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
ALLEGRO_COLOR color;
|
||||||
|
ALLEGRO_COLOR color_text = al_map_rgba_f(0.5, 0.5, 0.5, 0.2);
|
||||||
|
ALLEGRO_FONT* font = data->media.fonts[FONT_PS2P30]->al_font;
|
||||||
|
|
||||||
|
char text[200] = {' ', '\0'};
|
||||||
|
char num[5] = {'\0'};
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.ship_size; i++)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[i];
|
||||||
|
CLIENT_USER user;
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
color = al_map_rgba_f(0.5, 0.0, 0.0, 0.2);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
color = al_map_rgba_f(0.0, 0.5, 0.0, 0.2);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = al_map_rgba_f(0.5, 0.5, 0.0, 0.2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int j = 0; j < 3; j++)
|
||||||
|
if(data->network.users[j].id == ship->ID)
|
||||||
|
{
|
||||||
|
user = data->network.users[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
al_draw_text(font, color, al_get_text_width(font, text), 5, 0, user.nickname);
|
||||||
|
strcat(text, user.nickname);
|
||||||
|
al_draw_text(font, color, al_get_text_width(font, text), 5, 0, " - Ж:");
|
||||||
|
strcat(text, " - Ж:");
|
||||||
|
al_draw_textf(font, color_text, al_get_text_width(font, text), 5, 0, "%d", ship->lives);
|
||||||
|
sprintf(num, "%d", ship->lives);
|
||||||
|
strcat(text, num);
|
||||||
|
al_draw_text(font, color, al_get_text_width(font, text), 5, 0, " К:");
|
||||||
|
strcat(text, " К:");
|
||||||
|
al_draw_textf(font, color_text, al_get_text_width(font, text), 5, 0, "%d", ship->score);
|
||||||
|
sprintf(num, "%d ", ship->score);
|
||||||
|
strcat(text, num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* File: network_game.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_network_game
|
||||||
|
#define client_network_game
|
||||||
|
|
||||||
|
void networkgame_handling(CLIENT_DATA* data);
|
||||||
|
void networkgame_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void networkgame_create_objects(CLIENT_DATA* data);
|
||||||
|
void networkgame_enet_receive(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
static void networkgame_send_move_ship(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
static void networkgame_draw_ship(CLIENT_DATA* data);
|
||||||
|
static void networkgame_move_ship_up(CLIENT_DATA* data);
|
||||||
|
static void networkgame_move_ship_down(CLIENT_DATA* data);
|
||||||
|
static void networkgame_move_ship_left(CLIENT_DATA* data);
|
||||||
|
static void networkgame_move_ship_right(CLIENT_DATA* data);
|
||||||
|
static void networkgame_reset_ship_animation(CLIENT_DATA* data, int position);
|
||||||
|
static bool networkgame_dead_ship(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
static void networkgame_fire_bullet(CLIENT_DATA* data);
|
||||||
|
static void networkgame_draw_bullet(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
static void networkgame_draw_comet(CLIENT_DATA* data);
|
||||||
|
void networkgame_update_comet(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSION
|
||||||
|
***********************************************************/
|
||||||
|
static void networkgame_draw_explosions(CLIENT_DATA* data);
|
||||||
|
void networkgame_update_explosions(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* STATISTIC
|
||||||
|
***********************************************************/
|
||||||
|
static void networkgame_draw_statistic(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkjoin.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkjoin_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networkjoin_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkjoin_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_TAB:
|
||||||
|
networkjoin_change_selected(data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cl_print_field(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
cl_update_field(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networkjoin_push_button(data);
|
||||||
|
cl_enter_field(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkjoin_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
|
||||||
|
cl_draw_field(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* FIELD
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkjoin_init_field(CLIENT_DATA* data, int key_field, int key_font, const char* description)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKJOIN]->field_size > key_field)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_field(
|
||||||
|
data->pairing.interface[NETWORKJOIN]->field[key_field],
|
||||||
|
font->al_font, font->size, description,
|
||||||
|
(data->screen.width / 2) - al_get_text_width(font->al_font, description),
|
||||||
|
(block_size * (key_field + 3) - font->size / 2),
|
||||||
|
(data->screen.width / 2),
|
||||||
|
(block_size * (key_field + 3) - font->size / 2),
|
||||||
|
(data->screen.width / 2),
|
||||||
|
(block_size * (key_field + 3) + font->size / 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkjoin_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKJOIN]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKJOIN]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 5)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 5) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 5) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkjoin_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKJOIN_CREATE:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
if(networkjoin_check_field(data))
|
||||||
|
cl_change_state(data, NETWORKLIST);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKJOIN_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_FIELD)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->field_size; i++)
|
||||||
|
if(interface->field[i]->selected)
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case FIELD_NETWORKJOIN_NICKNAME:
|
||||||
|
interface->field[i]->enter = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkjoin_change_selected(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_change_selected(data->pairing.interface[data->state]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool networkjoin_check_field(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
int field_size = interface->field_size;
|
||||||
|
int field_filled_size = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < field_size; i++)
|
||||||
|
if(interface->field[i]->char_number > 0)
|
||||||
|
field_filled_size++;
|
||||||
|
|
||||||
|
return field_size == field_filled_size;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* File: network_join.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_network_join
|
||||||
|
#define client_network_join
|
||||||
|
|
||||||
|
enum networkjoin_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKJOIN_CREATE,
|
||||||
|
BUTTON_NETWORKJOIN_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum networkjoin_field
|
||||||
|
{
|
||||||
|
FIELD_NETWORKJOIN_NICKNAME
|
||||||
|
};
|
||||||
|
|
||||||
|
void networkjoin_handling(CLIENT_DATA* data);
|
||||||
|
void networkjoin_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void networkjoin_init_field(CLIENT_DATA* data, int key_field, int key_font, const char* description);
|
||||||
|
void networkjoin_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
|
||||||
|
static void networkjoin_push_button(CLIENT_DATA* data);
|
||||||
|
static void networkjoin_change_selected(CLIENT_DATA* data);
|
||||||
|
static bool networkjoin_check_field(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,303 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networklist.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networklist_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networklist_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networklist_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_TAB:
|
||||||
|
networklist_change_selected(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
cl_update_list(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networklist_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
|
||||||
|
networklist_enet_receive(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networklist_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
networklist_draw_list(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networklist_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKLIST]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKLIST]->button[key_button],
|
||||||
|
font->al_font, text,
|
||||||
|
data->screen.width - (750 * data->screen.scale_factor + 60) / 2,
|
||||||
|
block_size * (index + 6) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
data->screen.width - (750 * data->screen.scale_factor) - 30,
|
||||||
|
block_size * (index + 6) + (block_size / 4),
|
||||||
|
data->screen.width - 30,
|
||||||
|
block_size * (index + 6) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* LIST
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networklist_init_list(CLIENT_DATA* data, int key_font)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[NETWORKLIST]->list;
|
||||||
|
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
int item_height = ((data->screen.height - 15) - block_size * 2) / 3;
|
||||||
|
|
||||||
|
list->sx = 15;
|
||||||
|
list->sy = block_size * 2;
|
||||||
|
list->dx = data->screen.width - (750 * data->screen.scale_factor) - 60;
|
||||||
|
list->dy = data->screen.height - 15;
|
||||||
|
list->al_font = font->al_font;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
cl_add_list_item(
|
||||||
|
&list->item[i],
|
||||||
|
list->sx,
|
||||||
|
list->sy + (item_height * i),
|
||||||
|
list->dx,
|
||||||
|
list->sy + item_height + (item_height * i),
|
||||||
|
list->sx + 30,
|
||||||
|
(list->sy + (item_height * i)) + ((item_height / 2) - (font->size / 2)),
|
||||||
|
list->dx - font->size - 30,
|
||||||
|
list->sy + (item_height * i) + (item_height / 2),
|
||||||
|
font->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networklist_draw_list(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[NETWORKLIST]->list;
|
||||||
|
ALLEGRO_COLOR clr;
|
||||||
|
|
||||||
|
al_draw_rectangle(list->sx, list->sy, list->dx, list->dy, al_map_rgba_f(0.2, 0.2, 0.2, 0.2), 3);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if(i < data->network.count_game)
|
||||||
|
{
|
||||||
|
list->item[i].active = true;
|
||||||
|
|
||||||
|
CLIENT_LIST_ITEM item = list->item[i];
|
||||||
|
|
||||||
|
if(item.selected)
|
||||||
|
clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_rectangle(item.sx_item, item.sy_item, item.dx_item, item.dy_item, clr);
|
||||||
|
al_draw_text(list->al_font, al_map_rgb(255, 255, 255), item.x_h, item.y_h, 0, data->network.games[i].game_name);
|
||||||
|
|
||||||
|
if(data->network.games[i].count_connected == 3)
|
||||||
|
clr = al_map_rgba_f(0.5, 0.0, 0.0, 0.2);
|
||||||
|
else if(data->network.games[i].count_connected == 2)
|
||||||
|
clr = al_map_rgba_f(0.5, 0.5, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.0, 0.5, 0.0, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_circle(item.x_status, item.y_status, item.r_status, clr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
list->item[i].active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networklist_enet_receive(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
ENetEvent event;
|
||||||
|
CLIENT_MESSAGE_LIST* message;
|
||||||
|
CLIENT_MESSAGE_PARTY* messages;
|
||||||
|
|
||||||
|
while(enet_host_service(data->enet.client, &event, 0) > 0)
|
||||||
|
if(event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||||
|
{
|
||||||
|
message = (CLIENT_MESSAGE_LIST*)event.packet->data;
|
||||||
|
|
||||||
|
if(message->state == STATE_PARTY)
|
||||||
|
{
|
||||||
|
cl_change_state(data, NETWORKPARTY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_NETWORK* network = &data->network;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
network->games[i].id = message->games[i].id;
|
||||||
|
network->games[i].count_connected = message->games[i].count_connected;
|
||||||
|
strncpy(network->games[i].game_name, message->games[i].game_name, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
network->count_game = message->count_game;
|
||||||
|
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networklist_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[NETWORKLIST];
|
||||||
|
|
||||||
|
ENetPacket *packet;
|
||||||
|
CLIENT_MESSAGE_JOINGAME message;
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_LIST)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &interface->list;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(list->item[i].selected && data->network.games[i].count_connected < 3)
|
||||||
|
{
|
||||||
|
list->item[i].selected = false;
|
||||||
|
|
||||||
|
message.id = data->network.games[i].id;
|
||||||
|
message.state = STATE_PARTY;
|
||||||
|
packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKLIST_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void networklist_change_selected(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[NETWORKLIST];
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_LIST;
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_LIST)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_BUTTON;
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(interface->list.item[i].selected)
|
||||||
|
interface->list.item[i].selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* File: networklist.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.21
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_network_list
|
||||||
|
#define client_network_list
|
||||||
|
|
||||||
|
enum networkparty_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKLIST_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
void networklist_handling(CLIENT_DATA* data);
|
||||||
|
void networklist_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void networklist_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
|
||||||
|
void networklist_init_list(CLIENT_DATA* data, int key_font);
|
||||||
|
static void networklist_draw_list(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
static void networklist_enet_receive(CLIENT_DATA* data);
|
||||||
|
static void networklist_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void networklist_change_selected(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkmode.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkmode_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networkmode_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkmode_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networkmode_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkmode_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkmode_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKMODE]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKMODE]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 3)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkmode_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font && interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKMODE_CREATE:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKCREATE);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKMODE_JOIN:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKJOIN);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKMODE_OUT:
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* File: network.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_networkmode
|
||||||
|
#define client_networkmode
|
||||||
|
|
||||||
|
enum networkmode_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKMODE_CREATE,
|
||||||
|
BUTTON_NETWORKMODE_JOIN,
|
||||||
|
BUTTON_NETWORKMODE_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
void networkmode_handling(CLIENT_DATA* data);
|
||||||
|
void networkmode_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void networkmode_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void networkmode_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkout.h"
|
||||||
|
#include "networkgame.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkout_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
al_hide_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, NETWORKGAME);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networkout_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkout_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networkout_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
networkgame_update_explosions(data);
|
||||||
|
networkgame_update_comet(data);
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG3);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
|
||||||
|
networkgame_enet_receive(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkout_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG3);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkout_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKOUT]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKOUT]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 3)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkout_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKOUT_BACK:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
al_hide_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, NETWORKGAME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON_NETWORKOUT_MENU:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* File: networkout.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.27
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_networkout
|
||||||
|
#define client_networkout
|
||||||
|
|
||||||
|
enum networkout_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKOUT_BACK,
|
||||||
|
BUTTON_NETWORKOUT_MENU
|
||||||
|
};
|
||||||
|
|
||||||
|
void networkout_handling(CLIENT_DATA* data);
|
||||||
|
void networkout_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void networkout_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void networkout_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,433 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "networkparty.h"
|
||||||
|
#include "networkcreate.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkparty_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
if(data->network.is_creator)
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
else
|
||||||
|
networkparty_send_exit(data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
networkparty_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
networkparty_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_TAB:
|
||||||
|
networkparty_change_selected(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
cl_update_list(data);
|
||||||
|
cl_update_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
networkparty_push_button(data);
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
|
||||||
|
networkparty_enet_receive(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkparty_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
networkparty_draw_button(data);
|
||||||
|
networkparty_draw_list(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BUTTON
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkparty_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[NETWORKPARTY]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
if(key_button == BUTTON_NETWORKPARTY_OUT)
|
||||||
|
index = 1;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[NETWORKPARTY]->button[key_button],
|
||||||
|
font->al_font, text,
|
||||||
|
data->screen.width - (750 * data->screen.scale_factor + 60) / 2,
|
||||||
|
block_size * (index + 5) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
data->screen.width - (750 * data->screen.scale_factor) - 30,
|
||||||
|
block_size * (index + 5) + (block_size / 4),
|
||||||
|
data->screen.width - 30,
|
||||||
|
block_size * (index + 5) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_draw_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[NETWORKPARTY];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->al_font)
|
||||||
|
{
|
||||||
|
CLIENT_BUTTON* btn = interface->button[i];
|
||||||
|
|
||||||
|
if(data->network.is_creator)
|
||||||
|
{
|
||||||
|
if(i == BUTTON_NETWORKPARTY_READY || i == BUTTON_NETWORKPARTY_UNREADY)
|
||||||
|
{
|
||||||
|
btn->active = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->network.is_ready)
|
||||||
|
{
|
||||||
|
if(i == BUTTON_NETWORKPARTY_READY || i == BUTTON_NETWORKPARTY_START)
|
||||||
|
{
|
||||||
|
btn->active = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(i == BUTTON_NETWORKPARTY_UNREADY || i == BUTTON_NETWORKPARTY_START)
|
||||||
|
{
|
||||||
|
btn->active = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLEGRO_COLOR clr;
|
||||||
|
|
||||||
|
btn->active = true;
|
||||||
|
|
||||||
|
if(btn->selected)
|
||||||
|
clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_rectangle(btn->b_sx, btn->b_sy, btn->b_dx, btn->b_dy, clr);
|
||||||
|
al_draw_text(btn->al_font, al_map_rgb(255, 255, 255), btn->t_x, btn->t_y, ALLEGRO_ALIGN_CENTRE, btn->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* LIST
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void networkparty_init_list(CLIENT_DATA* data, int key_font)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[NETWORKPARTY]->list;
|
||||||
|
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
int item_height = ((data->screen.height - 15) - block_size * 2) / 3;
|
||||||
|
|
||||||
|
list->sx = 15;
|
||||||
|
list->sy = block_size * 2;
|
||||||
|
list->dx = data->screen.width - (750 * data->screen.scale_factor) - 60;
|
||||||
|
list->dy = data->screen.height - 15;
|
||||||
|
list->al_font = font->al_font;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
cl_add_list_item(
|
||||||
|
&list->item[i],
|
||||||
|
list->sx,
|
||||||
|
list->sy + (item_height * i),
|
||||||
|
list->dx,
|
||||||
|
list->sy + item_height + (item_height * i),
|
||||||
|
list->sx + 30,
|
||||||
|
(list->sy + (item_height * i)) + ((item_height / 2) - (font->size / 2)),
|
||||||
|
list->dx - font->size - 30,
|
||||||
|
list->sy + (item_height * i) + (item_height / 2),
|
||||||
|
font->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_draw_list(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &data->pairing.interface[NETWORKPARTY]->list;
|
||||||
|
ALLEGRO_COLOR clr;
|
||||||
|
|
||||||
|
al_draw_rectangle(list->sx, list->sy, list->dx, list->dy, al_map_rgba_f(0.2, 0.2, 0.2, 0.2), 3);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if(i < data->network.count_connected)
|
||||||
|
{
|
||||||
|
list->item[i].active = true;
|
||||||
|
|
||||||
|
CLIENT_LIST_ITEM item = list->item[i];
|
||||||
|
|
||||||
|
if(item.selected)
|
||||||
|
clr = al_map_rgba_f(0.4, 0.4, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.2, 0.2, 0.2, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_rectangle(item.sx_item, item.sy_item, item.dx_item, item.dy_item, clr);
|
||||||
|
al_draw_text(list->al_font, al_map_rgb(255, 255, 255), item.x_h, item.y_h, 0, data->network.users[i].nickname);
|
||||||
|
|
||||||
|
if(data->network.users[i].is_ready)
|
||||||
|
clr = al_map_rgba_f(0.0, 0.5, 0.0, 0.2);
|
||||||
|
else
|
||||||
|
clr = al_map_rgba_f(0.5, 0.0, 0.0, 0.2);
|
||||||
|
|
||||||
|
al_draw_filled_circle(item.x_status, item.y_status, item.r_status, clr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
list->item[i].active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void networkparty_enet_receive(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
ENetEvent event;
|
||||||
|
CLIENT_MESSAGE_PARTY* message;
|
||||||
|
|
||||||
|
while(enet_host_service(data->enet.client, &event, 0) > 0)
|
||||||
|
if(event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||||
|
{
|
||||||
|
message = (CLIENT_MESSAGE_PARTY*)event.packet->data;
|
||||||
|
|
||||||
|
if(message->state == STATE_LIST)
|
||||||
|
{
|
||||||
|
cl_change_state(data, NETWORKLIST);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(message->state == STATE_GAME)
|
||||||
|
{
|
||||||
|
cl_change_state(data, NETWORKGAME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_NETWORK* network = &data->network;
|
||||||
|
|
||||||
|
network->active = message->active;
|
||||||
|
network->count_connected = message->count_connected;
|
||||||
|
network->game_started = message->game_started;
|
||||||
|
strncpy(network->game_name, message->game_name, 40);
|
||||||
|
network->is_creator = message->is_creator;
|
||||||
|
network->is_ready = message->is_ready;
|
||||||
|
network->game_id = message->game_id;
|
||||||
|
network->user_id = message->user_id;
|
||||||
|
|
||||||
|
for(int i = 0; i < network->count_connected; i++)
|
||||||
|
{
|
||||||
|
network->users[i].id = message->users[i].id;
|
||||||
|
network->users[i].is_ready = message->users[i].is_ready;
|
||||||
|
strncpy(network->users[i].nickname, message->users[i].nickname, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[NETWORKPARTY];
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_NETWORKPARTY_START:
|
||||||
|
if(networkparty_check_users(data))
|
||||||
|
networkparty_send_start(data);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKPARTY_READY:
|
||||||
|
case BUTTON_NETWORKPARTY_UNREADY:
|
||||||
|
networkparty_send_ready(data);
|
||||||
|
break;
|
||||||
|
case BUTTON_NETWORKPARTY_OUT:
|
||||||
|
if(data->network.is_creator)
|
||||||
|
cl_change_state(data, NETWORKMODE);
|
||||||
|
else
|
||||||
|
networkparty_send_exit(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_LIST)
|
||||||
|
{
|
||||||
|
if(data->network.is_creator)
|
||||||
|
{
|
||||||
|
CLIENT_LIST* list = &interface->list;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(list->item[i].selected && data->network.users[i].id != data->network.user_id)
|
||||||
|
{
|
||||||
|
list->item[i].selected = false;
|
||||||
|
|
||||||
|
networkparty_send_kick(data, data->network.users[i].id);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_change_selected(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[NETWORKPARTY];
|
||||||
|
|
||||||
|
if(interface->selected == SELECTED_BUTTON)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_LIST;
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
}
|
||||||
|
else if(interface->selected == SELECTED_LIST)
|
||||||
|
{
|
||||||
|
interface->selected = SELECTED_BUTTON;
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
if(interface->list.item[i].selected)
|
||||||
|
interface->list.item[i].selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool networkparty_check_users(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
bool ready = true;
|
||||||
|
|
||||||
|
for(int i = 0; i < data->network.count_connected; i++)
|
||||||
|
if(!data->network.users[i].is_ready)
|
||||||
|
{
|
||||||
|
ready = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_send_exit(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_SENDPARTY message;
|
||||||
|
|
||||||
|
message.state = STATE_LIST;
|
||||||
|
message.kick_user = false;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_send_ready(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_SENDPARTY message;
|
||||||
|
|
||||||
|
message.state = STATE_PARTY;
|
||||||
|
message.is_ready = !data->network.is_ready;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_send_kick(CLIENT_DATA* data, int user_id)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_SENDPARTY message;
|
||||||
|
|
||||||
|
message.state = STATE_LIST;
|
||||||
|
message.kick_user = true;
|
||||||
|
message.user_id = user_id;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void networkparty_send_start(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_MESSAGE_SENDPARTY message;
|
||||||
|
|
||||||
|
message.state = STATE_GAME;
|
||||||
|
|
||||||
|
ENetPacket *packet = enet_packet_create(&message, sizeof(message), ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(data->enet.server, 0, packet);
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File: network_party.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_network_party
|
||||||
|
#define client_network_party
|
||||||
|
|
||||||
|
enum networklist_buttons
|
||||||
|
{
|
||||||
|
BUTTON_NETWORKPARTY_START,
|
||||||
|
BUTTON_NETWORKPARTY_READY,
|
||||||
|
BUTTON_NETWORKPARTY_UNREADY,
|
||||||
|
BUTTON_NETWORKPARTY_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
void networkparty_handling(CLIENT_DATA* data);
|
||||||
|
void networkparty_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
static void networkparty_enet_receive(CLIENT_DATA* data);
|
||||||
|
void networkparty_init_list(CLIENT_DATA* data, int key_font);
|
||||||
|
|
||||||
|
static void networkparty_draw_list(CLIENT_DATA* data);
|
||||||
|
void networkparty_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void networkparty_draw_button(CLIENT_DATA* data);
|
||||||
|
static void networkparty_push_button(CLIENT_DATA* data);
|
||||||
|
static void networkparty_change_selected(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
static bool networkparty_check_users(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
static void networkparty_send_exit(CLIENT_DATA* data);
|
||||||
|
static void networkparty_send_ready(CLIENT_DATA* data);
|
||||||
|
static void networkparty_send_kick(CLIENT_DATA* data, int user_id);
|
||||||
|
static void networkparty_send_start(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
#include "objects.h"
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
CLIENT_OBJECTS* cl_create_objects(CLIENT_OBJECTS* objects, int ship_size, int bullet_size, int comet_size, int explosion_size)
|
||||||
|
{
|
||||||
|
if(!objects)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = (CLIENT_OBJECTS*)malloc(sizeof(CLIENT_OBJECTS));
|
||||||
|
show_message_error(objects, "Failed to allocate space for CLIENT_OBJECTS");
|
||||||
|
}
|
||||||
|
|
||||||
|
objects->ship_size = ship_size;
|
||||||
|
objects->bullet_size = bullet_size;
|
||||||
|
objects->comet_size = comet_size;
|
||||||
|
objects->explosion_size = explosion_size;
|
||||||
|
|
||||||
|
objects->ships = cl_create_ships(ship_size);
|
||||||
|
objects->bullets = cl_create_bullets(bullet_size);
|
||||||
|
objects->comets = cl_create_comets(comet_size);
|
||||||
|
objects->explosions = cl_create_explosions(explosion_size);
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_free_objects(CLIENT_OBJECTS* objects)
|
||||||
|
{
|
||||||
|
cl_destroy_objects(objects);
|
||||||
|
free(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_destroy_objects(CLIENT_OBJECTS* objects)
|
||||||
|
{
|
||||||
|
if(objects->ship_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->ship_size; i++)
|
||||||
|
free(objects->ships[i]);
|
||||||
|
free(objects->ships);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->bullet_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
free(objects->bullets[i]);
|
||||||
|
free(objects->bullets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->comet_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
free(objects->comets[i]);
|
||||||
|
free(objects->comets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(objects->explosion_size > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
free(objects->explosions[i]);
|
||||||
|
free(objects->explosions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_SHIP** cl_create_ships(int size)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP** ships = (CLIENT_SHIP**)malloc(sizeof(CLIENT_SHIP*) * size);
|
||||||
|
show_message_error(ships, "Failed to allocate space for CLIENT_SHIP collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ships[i] = (CLIENT_SHIP*)malloc(sizeof(CLIENT_SHIP));
|
||||||
|
show_message_error(ships[i], "Failed to allocate space for CLIENT_SHIP");
|
||||||
|
ships[i]->image = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ships;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_BULLET** cl_create_bullets(int size)
|
||||||
|
{
|
||||||
|
CLIENT_BULLET** bullets = (CLIENT_BULLET**)malloc(sizeof(CLIENT_BULLET*) * size);
|
||||||
|
show_message_error(bullets, "Failed to allocate space for CLIENT_BULLET collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
bullets[i] = (CLIENT_BULLET*)malloc(sizeof(CLIENT_BULLET));
|
||||||
|
show_message_error(bullets[i], "Failed to allocate space for CLIENT_BULLET");
|
||||||
|
}
|
||||||
|
|
||||||
|
return bullets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_COMET** cl_create_comets(int size)
|
||||||
|
{
|
||||||
|
CLIENT_COMET** comets = (CLIENT_COMET**)malloc(sizeof(CLIENT_COMET*) * size);
|
||||||
|
show_message_error(comets, "Failed to allocate space for CLIENT_COMET collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
comets[i] = (CLIENT_COMET*)malloc(sizeof(CLIENT_COMET));
|
||||||
|
show_message_error(comets[i], "Failed to allocate space for CLIENT_COMET");
|
||||||
|
comets[i]->image = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return comets;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLIENT_EXPLOSION** cl_create_explosions(int size)
|
||||||
|
{
|
||||||
|
CLIENT_EXPLOSION** explosions = (CLIENT_EXPLOSION**)malloc(sizeof(CLIENT_EXPLOSION*) * size);
|
||||||
|
show_message_error(explosions, "Failed to allocate space for CLIENT_EXPLOSION collection");
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
explosions[i] = (CLIENT_EXPLOSION*)malloc(sizeof(CLIENT_EXPLOSION));
|
||||||
|
show_message_error(explosions[i], "Failed to allocate space for CLIENT_EXPLOSION");
|
||||||
|
explosions[i]->image = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return explosions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_init_ships(CLIENT_OBJECTS* objects, int key_ship, int ID, int animation_columns, int animation_direction, int animation_row, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int lives, int max_frame, int score, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = objects->ships[key_ship];
|
||||||
|
|
||||||
|
ship->ID = ID;
|
||||||
|
ship->animation_columns = animation_columns;
|
||||||
|
ship->animation_direction = animation_direction;
|
||||||
|
ship->animation_row = animation_row;
|
||||||
|
ship->boundx = boundx;
|
||||||
|
ship->boundy = boundy;
|
||||||
|
ship->cur_frame = cur_frame;
|
||||||
|
ship->frame_count = frame_count;
|
||||||
|
ship->frame_delay = frame_delay;
|
||||||
|
ship->frame_height = frame_height;
|
||||||
|
ship->frame_width = frame_width;
|
||||||
|
ship->image = image;
|
||||||
|
ship->lives = lives;
|
||||||
|
ship->max_frame = max_frame;
|
||||||
|
ship->score = score;
|
||||||
|
ship->speed = speed;
|
||||||
|
ship->x = x;
|
||||||
|
ship->y = y;
|
||||||
|
ship->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_init_bullets(CLIENT_OBJECTS* objects, int key_bullet, int ID, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
CLIENT_BULLET* bullet = objects->bullets[key_bullet];
|
||||||
|
|
||||||
|
bullet->ID = ID;
|
||||||
|
bullet->live = false;
|
||||||
|
bullet->speed = speed;
|
||||||
|
bullet->x = x;
|
||||||
|
bullet->y = y;
|
||||||
|
bullet->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_init_comets(CLIENT_OBJECTS* objects, int key_comet, int ID, int animation_columns, int animation_direction, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int speed, int x, int y)
|
||||||
|
{
|
||||||
|
CLIENT_COMET* comet = objects->comets[key_comet];
|
||||||
|
|
||||||
|
comet->ID = ID;
|
||||||
|
comet->animation_columns = animation_columns;
|
||||||
|
comet->animation_direction = animation_direction;
|
||||||
|
comet->boundx = boundx;
|
||||||
|
comet->boundy = boundy;
|
||||||
|
comet->cur_frame = cur_frame;
|
||||||
|
comet->frame_count = frame_count;
|
||||||
|
comet->frame_delay = frame_delay;
|
||||||
|
comet->frame_height = frame_height;
|
||||||
|
comet->frame_width = frame_width;
|
||||||
|
comet->image = image;
|
||||||
|
comet->max_frame = max_frame;
|
||||||
|
comet->speed = speed;
|
||||||
|
comet->live = false;
|
||||||
|
comet->x = x;
|
||||||
|
comet->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cl_init_explosions(CLIENT_OBJECTS* objects, int key_explosion, int animation_columns, int animation_direction, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int x, int y)
|
||||||
|
{
|
||||||
|
CLIENT_EXPLOSION* explosion = objects->explosions[key_explosion];
|
||||||
|
|
||||||
|
explosion->animation_columns = animation_columns;
|
||||||
|
explosion->animation_direction = animation_direction;
|
||||||
|
explosion->cur_frame = cur_frame;
|
||||||
|
explosion->frame_count = frame_count;
|
||||||
|
explosion->frame_delay = frame_delay;
|
||||||
|
explosion->frame_height = frame_height;
|
||||||
|
explosion->frame_width = frame_width;
|
||||||
|
explosion->image = image;
|
||||||
|
explosion->live = false;
|
||||||
|
explosion->max_frame = max_frame;
|
||||||
|
explosion->x = x;
|
||||||
|
explosion->y = y;
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* File: objects.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_objects
|
||||||
|
#define client_objects
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <allegro5/allegro.h>
|
||||||
|
|
||||||
|
typedef struct cl_ship
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int lives;
|
||||||
|
int speed;
|
||||||
|
int boundx;
|
||||||
|
int boundy;
|
||||||
|
int score;
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
|
||||||
|
int animation_row;
|
||||||
|
|
||||||
|
ALLEGRO_BITMAP *image;
|
||||||
|
} CLIENT_SHIP;
|
||||||
|
|
||||||
|
typedef struct cl_bullet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
int speed;
|
||||||
|
bool active;
|
||||||
|
} CLIENT_BULLET;
|
||||||
|
|
||||||
|
typedef struct cl_comet
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
int speed;
|
||||||
|
int boundx;
|
||||||
|
int boundy;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
|
||||||
|
ALLEGRO_BITMAP *image;
|
||||||
|
} CLIENT_COMET;
|
||||||
|
|
||||||
|
typedef struct cl_explosion
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool live;
|
||||||
|
|
||||||
|
int max_frame;
|
||||||
|
int cur_frame;
|
||||||
|
int frame_count;
|
||||||
|
int frame_delay;
|
||||||
|
int frame_width;
|
||||||
|
int frame_height;
|
||||||
|
int animation_columns;
|
||||||
|
int animation_direction;
|
||||||
|
|
||||||
|
ALLEGRO_BITMAP *image;
|
||||||
|
} CLIENT_EXPLOSION;
|
||||||
|
|
||||||
|
typedef struct cl_objects
|
||||||
|
{
|
||||||
|
CLIENT_SHIP** ships;
|
||||||
|
int ship_size;
|
||||||
|
CLIENT_BULLET** bullets;
|
||||||
|
int bullet_size;
|
||||||
|
CLIENT_COMET** comets;
|
||||||
|
int comet_size;
|
||||||
|
CLIENT_EXPLOSION** explosions;
|
||||||
|
int explosion_size;
|
||||||
|
} CLIENT_OBJECTS;
|
||||||
|
|
||||||
|
CLIENT_OBJECTS* cl_create_objects(CLIENT_OBJECTS* data, int ship_size, int bullet_size, int comet_size, int explosion_size);
|
||||||
|
void cl_free_objects(CLIENT_OBJECTS* objects);
|
||||||
|
void cl_destroy_objects(CLIENT_OBJECTS* objects);
|
||||||
|
|
||||||
|
static CLIENT_SHIP** cl_create_ships(int size);
|
||||||
|
static CLIENT_BULLET** cl_create_bullets(int size);
|
||||||
|
static CLIENT_COMET** cl_create_comets(int size);
|
||||||
|
static CLIENT_EXPLOSION** cl_create_explosions(int size);
|
||||||
|
|
||||||
|
void cl_init_ships(CLIENT_OBJECTS* objects, int key_ship, int ID, int animation_columns, int animation_direction, int animation_row, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int lives, int max_frame, int score, int speed, int x, int y);
|
||||||
|
void cl_init_bullets(CLIENT_OBJECTS* objects, int key_bullet, int ID, int speed, int x, int y);
|
||||||
|
void cl_init_comets(CLIENT_OBJECTS* objects, int key_comet, int ID, int animation_columns, int animation_direction, int boundx, int boundy, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int speed, int x, int y);
|
||||||
|
void cl_init_explosions(CLIENT_OBJECTS* objects, int key_explosion, int animation_columns, int animation_direction, int cur_frame,
|
||||||
|
int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int x, int y);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,133 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "pause.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void pause_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
al_hide_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, SINGLE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
cl_select_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = true;
|
||||||
|
pause_push_button(data);
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
pause_push_button(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_ENTER:
|
||||||
|
data->keys[ENTER] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
cl_update_button(data);
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
pause_push_button(data);
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void pause_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
cl_draw_header(data);
|
||||||
|
cl_draw_button(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void pause_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text)
|
||||||
|
{
|
||||||
|
if(data->pairing.interface[PAUSE]->button_size > key_button)
|
||||||
|
{
|
||||||
|
CLIENT_FONT* font = data->media.fonts[key_font];
|
||||||
|
int block_size = data->screen.height / 8;
|
||||||
|
|
||||||
|
cl_add_interface_button(
|
||||||
|
data->pairing.interface[PAUSE]->button[key_button],
|
||||||
|
font->al_font, text, data->screen.width / 2,
|
||||||
|
(block_size * (key_button + 3)) + (block_size / 4) + (block_size / 2) - font->size,
|
||||||
|
(data->screen.width / 2) - (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + (block_size / 4),
|
||||||
|
(data->screen.width / 2) + (750 * data->screen.scale_factor) / 2,
|
||||||
|
block_size * (key_button + 3) + block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pause_push_button(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_INTERFACE* interface = data->pairing.interface[data->state];
|
||||||
|
|
||||||
|
for(int i = 0; i < interface->button_size; i++)
|
||||||
|
if(interface->button[i]->selected)
|
||||||
|
{
|
||||||
|
cl_play_sound(data, SAMPLE_ENTER);
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BUTTON_PAUSE_BACK:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
al_hide_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, SINGLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BUTTON_PAUSE_MENU:
|
||||||
|
{
|
||||||
|
interface->button[i]->selected = false;
|
||||||
|
cl_change_state(data, MENU);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* File: pause.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_pause
|
||||||
|
#define client_pause
|
||||||
|
|
||||||
|
enum pause_buttons
|
||||||
|
{
|
||||||
|
BUTTON_PAUSE_BACK,
|
||||||
|
BUTTON_PAUSE_MENU
|
||||||
|
};
|
||||||
|
|
||||||
|
void pause_handling(CLIENT_DATA* data);
|
||||||
|
void pause_draw(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
void pause_init_button(CLIENT_DATA* data, int key_button, int key_font, const char* text);
|
||||||
|
static void pause_push_button(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,462 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "single.h"
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* HANDLING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void single_handling(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
if(data->event.current.type == ALLEGRO_EVENT_KEY_DOWN)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
{
|
||||||
|
if(!data->keys[ESCAPE])
|
||||||
|
{
|
||||||
|
data->keys[ESCAPE] = true;
|
||||||
|
al_show_mouse_cursor(data->screen.display);
|
||||||
|
cl_change_state(data, PAUSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = true;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = true;
|
||||||
|
cl_fire_bullet(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_KEY_UP)
|
||||||
|
{
|
||||||
|
switch (data->event.current.keyboard.keycode)
|
||||||
|
{
|
||||||
|
case ALLEGRO_KEY_ESCAPE:
|
||||||
|
data->keys[ESCAPE] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_LEFT:
|
||||||
|
data->keys[LEFT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_RIGHT:
|
||||||
|
data->keys[RIGHT] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_UP:
|
||||||
|
data->keys[UP] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_DOWN:
|
||||||
|
data->keys[DOWN] = false;
|
||||||
|
break;
|
||||||
|
case ALLEGRO_KEY_SPACE:
|
||||||
|
data->keys[SPACE] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_AXES)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(data->event.current.type == ALLEGRO_EVENT_TIMER)
|
||||||
|
{
|
||||||
|
data->render = true;
|
||||||
|
|
||||||
|
if(data->keys[UP])
|
||||||
|
cl_move_ship_up(data);
|
||||||
|
else if(data->keys[DOWN])
|
||||||
|
cl_move_ship_down(data);
|
||||||
|
else
|
||||||
|
cl_reset_ship_animation(data, 1);
|
||||||
|
|
||||||
|
if(data->keys[LEFT])
|
||||||
|
cl_move_ship_left(data);
|
||||||
|
else if(data->keys[RIGHT])
|
||||||
|
cl_move_ship_right(data);
|
||||||
|
else
|
||||||
|
cl_reset_ship_animation(data, 2);
|
||||||
|
|
||||||
|
cl_update_background(data, BG1);
|
||||||
|
cl_update_background(data, BG3);
|
||||||
|
cl_update_background(data, BG2);
|
||||||
|
|
||||||
|
cl_update_explosions(data);
|
||||||
|
cl_update_bullet(data);
|
||||||
|
cl_start_comet(data);
|
||||||
|
cl_update_comet(data);
|
||||||
|
cl_collide_bullet(data);
|
||||||
|
cl_collide_comet(data);
|
||||||
|
|
||||||
|
if(cl_dead_ship(data))
|
||||||
|
{
|
||||||
|
cl_change_state(data, GAMEOVER);
|
||||||
|
al_show_mouse_cursor(data->screen.display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* DRAW
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void single_draw(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
cl_draw_background(data, BG1);
|
||||||
|
cl_draw_background(data, BG3);
|
||||||
|
cl_draw_background(data, BG2);
|
||||||
|
|
||||||
|
cl_draw_ship(data);
|
||||||
|
cl_draw_bullet(data);
|
||||||
|
cl_draw_comet(data);
|
||||||
|
cl_draw_explosions(data);
|
||||||
|
|
||||||
|
cl_draw_statistic(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* PROCESSING
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
void cl_init_objects(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
cl_create_objects(objects, 1, 5, 10, 5);
|
||||||
|
cl_init_ships(objects, 0, 0, 3, 1, 1, 10, 12, 0, 0, 50, 41, 46, data->media.bitmaps[SHIP_R]->al_bitmap, 3, 3, 0, 6, 20, data->screen.height / 2);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
cl_init_bullets(objects, i, 0, 10, 0, 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
cl_init_comets(objects, i, 0, 21, rand() % 2 ? 1 : -1, 35, 35, 0, 0, 2, 96, 96, data->media.bitmaps[COMET]->al_bitmap, 143, 5, 0, 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
cl_init_explosions(objects, i, 8, 1, 0, 0, 1, 128, 128, data->media.bitmaps[EXPLOSION]->al_bitmap, 31, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_draw_ship(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
int fx = (ship->cur_frame % ship->animation_columns) * ship->frame_width;
|
||||||
|
int fy = ship->animation_row * ship->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(ship->image, fx, fy, ship->frame_width, ship->frame_height,
|
||||||
|
ship->x - ship->frame_width / 2, ship->y - ship->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_move_ship_up(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
ship->animation_row = 0;
|
||||||
|
ship->y -= ship->speed;
|
||||||
|
if(ship->y < 0)
|
||||||
|
ship->y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_move_ship_down(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
ship->animation_row = 2;
|
||||||
|
ship->y += ship->speed;
|
||||||
|
if(ship->y > data->screen.height)
|
||||||
|
ship->y = data->screen.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_move_ship_left(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
ship->cur_frame = 2;
|
||||||
|
ship->x -= ship->speed;
|
||||||
|
if(ship->x < 0)
|
||||||
|
ship->x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_move_ship_right(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
ship->cur_frame = 1;
|
||||||
|
ship->x += ship->speed;
|
||||||
|
if(ship->x > 900 * data->screen.scale_factor)
|
||||||
|
ship->x = 900 * data->screen.scale_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_reset_ship_animation(CLIENT_DATA* data, int position)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
|
||||||
|
if(position == 1)
|
||||||
|
ship->animation_row = 1;
|
||||||
|
else
|
||||||
|
ship->cur_frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool cl_dead_ship(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
return data->objects.ships[0]->lives <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_draw_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
if(objects->bullets[i]->live)
|
||||||
|
al_draw_filled_circle(objects->bullets[i]->x, objects->bullets[i]->y, 2, al_map_rgb(255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_fire_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.bullet_size; i++)
|
||||||
|
if(!objects->bullets[i]->live)
|
||||||
|
{
|
||||||
|
objects->bullets[i]->x = objects->ships[0]->x + 17;
|
||||||
|
objects->bullets[i]->y = objects->ships[0]->y;
|
||||||
|
objects->bullets[i]->live = true;
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_SHOT);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_update_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
|
||||||
|
for(int i = 0; i < data->objects.bullet_size; i++)
|
||||||
|
if(objects->bullets[i]->live)
|
||||||
|
{
|
||||||
|
objects->bullets[i]->x += objects->bullets[i]->speed;
|
||||||
|
if(objects->bullets[i]->x > data->screen.width)
|
||||||
|
objects->bullets[i]->live = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_collide_bullet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_SHIP* ship = objects->ships[0];
|
||||||
|
CLIENT_BULLET** bullets = objects->bullets;
|
||||||
|
CLIENT_COMET** comets = objects->comets;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->bullet_size; i++)
|
||||||
|
if(bullets[i]->live)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < objects->comet_size; j++)
|
||||||
|
if(comets[j]->live)
|
||||||
|
{
|
||||||
|
if(bullets[i]->x > (comets[j]->x - comets[j]->boundx) &&
|
||||||
|
bullets[i]->x < (comets[j]->x + comets[j]->boundx) &&
|
||||||
|
bullets[i]->y > (comets[j]->y - comets[j]->boundy) &&
|
||||||
|
bullets[i]->y < (comets[j]->y + comets[j]->boundy))
|
||||||
|
{
|
||||||
|
bullets[i]->live = false;
|
||||||
|
comets[j]->live = false;
|
||||||
|
|
||||||
|
ship->score++;
|
||||||
|
|
||||||
|
cl_start_explosions(data, bullets[i]->x, bullets[i]->y);
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_BOOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_draw_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_COMET** comets = objects->comets;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
if(comets[i]->live)
|
||||||
|
{
|
||||||
|
int fx = (comets[i]->cur_frame % comets[i]->animation_columns) * comets[i]->frame_width;
|
||||||
|
int fy = (comets[i]->cur_frame / comets[i]->animation_columns) * comets[i]->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(comets[i]->image, fx, fy, comets[i]->frame_width, comets[i]->frame_height,
|
||||||
|
comets[i]->x - comets[i]->frame_width / 2, comets[i]->y - comets[i]->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_start_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_COMET** comets = objects->comets;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
if(!comets[i]->live)
|
||||||
|
if(rand() % 500 == 0)
|
||||||
|
{
|
||||||
|
comets[i]->live = true;
|
||||||
|
comets[i]->x = data->screen.width;
|
||||||
|
comets[i]->y = 30 + rand() % (data->screen.height - 60);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_update_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_COMET** comets = objects->comets;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
if(comets[i]->live)
|
||||||
|
{
|
||||||
|
if(++comets[i]->frame_count >= comets[i]->frame_delay)
|
||||||
|
{
|
||||||
|
comets[i]->cur_frame += comets[i]->animation_direction;
|
||||||
|
if(comets[i]->cur_frame >= comets[i]->max_frame)
|
||||||
|
comets[i]->cur_frame = 0;
|
||||||
|
else if(comets[i]->cur_frame <= 0)
|
||||||
|
comets[i]->cur_frame = comets[i]->max_frame - 1;
|
||||||
|
|
||||||
|
comets[i]->frame_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
comets[i]->x -= comets[i]->speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_collide_comet(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
CLIENT_COMET** comets = objects->comets;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->comet_size; i++)
|
||||||
|
if(comets[i]->live)
|
||||||
|
{
|
||||||
|
if((comets[i]->x - comets[i]->boundx) < (ship->x + ship->boundx) &&
|
||||||
|
(comets[i]->x + comets[i]->boundx) > (ship->x - ship->boundx) &&
|
||||||
|
(comets[i]->y - comets[i]->boundy) < (ship->y + ship->boundy) &&
|
||||||
|
(comets[i]->y + comets[i]->boundy) > (ship->y - ship->boundy))
|
||||||
|
{
|
||||||
|
ship->lives--;
|
||||||
|
comets[i]->live = false;
|
||||||
|
|
||||||
|
cl_start_explosions(data, ship->x, ship->y);
|
||||||
|
|
||||||
|
cl_play_sound(data, SAMPLE_BOOM);
|
||||||
|
}
|
||||||
|
else if(comets[i]->x < 0)
|
||||||
|
{
|
||||||
|
comets[i]->live = false;
|
||||||
|
ship->lives--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSION
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_draw_explosions(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_EXPLOSION** explosions = objects->explosions;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
if(explosions[i]->live)
|
||||||
|
{
|
||||||
|
int fx = (explosions[i]->cur_frame % explosions[i]->animation_columns) * explosions[i]->frame_width;
|
||||||
|
int fy = (explosions[i]->cur_frame / explosions[i]->animation_columns) * explosions[i]->frame_height;
|
||||||
|
|
||||||
|
al_draw_bitmap_region(explosions[i]->image, fx, fy, explosions[i]->frame_width, explosions[i]->frame_height,
|
||||||
|
explosions[i]->x - explosions[i]->frame_width / 2, explosions[i]->y - explosions[i]->frame_height / 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_start_explosions(CLIENT_DATA* data, int x, int y)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_EXPLOSION** explosions = objects->explosions;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
if(!explosions[i]->live)
|
||||||
|
{
|
||||||
|
explosions[i]->live = true;
|
||||||
|
explosions[i]->x = x;
|
||||||
|
explosions[i]->y = y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cl_update_explosions(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_OBJECTS* objects = &data->objects;
|
||||||
|
CLIENT_EXPLOSION** explosions = objects->explosions;
|
||||||
|
|
||||||
|
for(int i = 0; i < objects->explosion_size; i++)
|
||||||
|
if(explosions[i]->live)
|
||||||
|
if(++explosions[i]->frame_count >= explosions[i]->frame_delay)
|
||||||
|
{
|
||||||
|
explosions[i]->cur_frame += explosions[i]->animation_direction;
|
||||||
|
if(explosions[i]->cur_frame >= explosions[i]->max_frame)
|
||||||
|
{
|
||||||
|
explosions[i]->cur_frame = 0;
|
||||||
|
explosions[i]->live = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
explosions[i]->frame_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* STATISTIC
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
static void cl_draw_statistic(CLIENT_DATA* data)
|
||||||
|
{
|
||||||
|
CLIENT_SHIP* ship = data->objects.ships[0];
|
||||||
|
ALLEGRO_COLOR color = al_map_rgba_f(0.5, 0.0, 0.0, 0.2);
|
||||||
|
ALLEGRO_COLOR color_text = al_map_rgba_f(0.5, 0.5, 0.5, 0.2);
|
||||||
|
ALLEGRO_FONT* font = data->media.fonts[FONT_PS2P30]->al_font;
|
||||||
|
|
||||||
|
char text[200] = {' ', '\0'};
|
||||||
|
char num[5] = {'\0'};
|
||||||
|
|
||||||
|
al_draw_text(font, color, al_get_text_width(font, text), 5, 0, "ЖИЗНИ:");
|
||||||
|
strcat(text, "ЖИЗНИ:");
|
||||||
|
al_draw_textf(font, color_text, al_get_text_width(font, text), 5, 0, "%d", ship->lives);
|
||||||
|
sprintf(num, "%d", ship->lives);
|
||||||
|
strcat(text, num);
|
||||||
|
al_draw_text(font, color, al_get_text_width(font, text), 5, 0, " КОМЕТЫ:");
|
||||||
|
strcat(text, " КОМЕТЫ:");
|
||||||
|
al_draw_textf(font, color_text, al_get_text_width(font, text), 5, 0, "%d", ship->score);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* File: single.h
|
||||||
|
* Author: Alexander Zhirov
|
||||||
|
* Connection with me (telegram messenger): @alexanderzhirov
|
||||||
|
*
|
||||||
|
* Created on 2020.06.08
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef client_single
|
||||||
|
#define client_single
|
||||||
|
|
||||||
|
void single_handling(CLIENT_DATA* data);
|
||||||
|
void single_draw(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
void cl_init_objects(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* SHIP
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_draw_ship(CLIENT_DATA* data);
|
||||||
|
static void cl_move_ship_up(CLIENT_DATA* data);
|
||||||
|
static void cl_move_ship_down(CLIENT_DATA* data);
|
||||||
|
static void cl_move_ship_left(CLIENT_DATA* data);
|
||||||
|
static void cl_move_ship_right(CLIENT_DATA* data);
|
||||||
|
static void cl_reset_ship_animation(CLIENT_DATA* data, int position);
|
||||||
|
static bool cl_dead_ship(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* BULLET
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_draw_bullet(CLIENT_DATA* data);
|
||||||
|
static void cl_fire_bullet(CLIENT_DATA* data);
|
||||||
|
static void cl_update_bullet(CLIENT_DATA* data);
|
||||||
|
static void cl_collide_bullet(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* COMET
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_draw_comet(CLIENT_DATA* data);
|
||||||
|
static void cl_start_comet(CLIENT_DATA* data);
|
||||||
|
static void cl_update_comet(CLIENT_DATA* data);
|
||||||
|
static void cl_collide_comet(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* EXPLOSIONS
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_draw_explosions(CLIENT_DATA* data);
|
||||||
|
static void cl_start_explosions(CLIENT_DATA* data, int x, int y);
|
||||||
|
static void cl_update_explosions(CLIENT_DATA* data);
|
||||||
|
/************************************************************
|
||||||
|
* STATISTIC
|
||||||
|
***********************************************************/
|
||||||
|
static void cl_draw_statistic(CLIENT_DATA* data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 230 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 82 KiB |