First commit
This commit is contained in:
commit
c98d6bf396
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
buid/
|
||||||
|
buid/**
|
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
### Introduction
|
||||||
|
This personal project is for making some simulator in C for the understanding of the Astrophysics, like the gravity.
|
||||||
|
I use the library SDL2 for the graphics.
|
||||||
|
|
||||||
|
FYI, I am not an expert in astrophysics, it's not my field, but just a hobby. If you find some wrong maths calculation, please, let me know.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
For executing the code, you must install these packages:
|
||||||
|
|
||||||
|
```
|
||||||
|
apt install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
The `gravity.yml` file contains all data for the physics laws, like the gravity or the data of the planet. You can change these datas and you can see hoz the gravity.
|
||||||
|
|
||||||
|
### Projectile
|
||||||
|
For understanding the gravity, we can simulate the launch of a projectile and to see what happens. We can play with that and change some informations regarding the projectile and the planet.
|
||||||
|
|
48
argparser.c
Normal file
48
argparser.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "argparser.h"
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
printf("Cosmology: -c <param file> [--debug]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int getArgs(char *arg) {
|
||||||
|
int res = FALSE;
|
||||||
|
int i;
|
||||||
|
/* List arguments */
|
||||||
|
char listArgs[3][BUF_SIZE];
|
||||||
|
strcpy(listArgs[0], "-c"); // Gravity
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++){
|
||||||
|
if(strcmp(listArgs[i], arg) == 0)
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res == FALSE){
|
||||||
|
printf("%s: unknown\n", arg);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int getArgsOptional(char *arg){
|
||||||
|
int res = FALSE;
|
||||||
|
int i;
|
||||||
|
/* List arguments */
|
||||||
|
char listArgs[1][BUF_SIZE];
|
||||||
|
strcpy(listArgs[0], "--debug");
|
||||||
|
|
||||||
|
for(i = 0; i < 1; i++){
|
||||||
|
if(strcmp(listArgs[i], arg) == 0)
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int checkParamFileExist(char *path){
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
|
||||||
|
if (f == NULL)
|
||||||
|
return -1;
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
12
argparser.h
Normal file
12
argparser.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef H_ARGPARSER
|
||||||
|
#define H_ARGPARSER
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "constantes.h"
|
||||||
|
|
||||||
|
void usage();
|
||||||
|
int getArgs(char *);
|
||||||
|
int getArgsOptional(char *);
|
||||||
|
int checkParamFileExist(char *);
|
||||||
|
|
||||||
|
#endif
|
BIN
build/argparser.o
Normal file
BIN
build/argparser.o
Normal file
Binary file not shown.
BIN
build/functions.o
Normal file
BIN
build/functions.o
Normal file
Binary file not shown.
BIN
build/gravity.o
Normal file
BIN
build/gravity.o
Normal file
Binary file not shown.
BIN
build/init_sdl.o
Normal file
BIN
build/init_sdl.o
Normal file
Binary file not shown.
BIN
build/main.o
Normal file
BIN
build/main.o
Normal file
Binary file not shown.
BIN
build/motion.o
Normal file
BIN
build/motion.o
Normal file
Binary file not shown.
BIN
build/projectile.o
Normal file
BIN
build/projectile.o
Normal file
Binary file not shown.
BIN
build/yaml.o
Normal file
BIN
build/yaml.o
Normal file
Binary file not shown.
27
constantes.h
Normal file
27
constantes.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef H_CONSTANTES
|
||||||
|
#define H_CONSTANTES
|
||||||
|
|
||||||
|
#define TRUE 0
|
||||||
|
#define FALSE 1
|
||||||
|
|
||||||
|
#define BUF_SIZE 128
|
||||||
|
|
||||||
|
/* Structure to define a planet */
|
||||||
|
struct object{
|
||||||
|
char name[BUF_SIZE];
|
||||||
|
double rayon;
|
||||||
|
double masse;
|
||||||
|
double grav;
|
||||||
|
int eccentricity;
|
||||||
|
double orbital; // Orbital in second
|
||||||
|
double aphelie; // In meters
|
||||||
|
double perihelie; // In meters
|
||||||
|
double semi_axe; // In meters
|
||||||
|
double orbital_speed; // In meters/s
|
||||||
|
};
|
||||||
|
|
||||||
|
struct constantes {
|
||||||
|
double grav; // Newton gravitational
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
18
exec.sh
Executable file
18
exec.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# main -c gravity.yml
|
||||||
|
|
||||||
|
#gcc sdl/init_sdl.c sdl/projectile.c sdl/orbitalSystem.c argparser.c yaml.c gravity.c main.c -lm -lpthread -lSDL2 -lSDL2_image -lSDL2_ttf -o main && ./main $1 $2 $3
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c sdl/init_sdl.c -o build/init_sdl.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c sdl/projectile.c -o build/projectile.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c argparser.c -o build/argparser.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c functions.c -o build/functions.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c yaml.c -o build/yaml.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c gravity.c -o build/gravity.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c motion.c -o build/motion.o
|
||||||
|
##gcc -S -o build/gravity.o gravity.c
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf -Wunused-variable -c main.c -o build/main.o
|
||||||
|
#gcc -lm -lSDL2 -lSDL2_image -lSDL2_ttf build/init_sdl.o build/projectile.o build/argparser.o build/yaml.o build/functions.o build/gravity.o build/motion.o build/main.o -o build/main && ./build/main $1 $2 $3
|
||||||
|
|
||||||
|
|
||||||
|
gcc functions.c motion.c sdl/init_sdl.c sdl/projectile.c argparser.c yaml.c gravity.c main.c -lm -lpthread -lSDL2 -lSDL2_image -lSDL2_ttf -o main && ./main $1 $2 $3
|
12
functions.c
Normal file
12
functions.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "functions.h"
|
||||||
|
|
||||||
|
int fileExist(char *path){
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
|
||||||
|
if (f == NULL)
|
||||||
|
return -1;
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
6
functions.h
Normal file
6
functions.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef H_FUNCTIONS
|
||||||
|
#define H_FUNCTIONS
|
||||||
|
|
||||||
|
int fileExist(char *);
|
||||||
|
|
||||||
|
#endif
|
10
gravity.c
Normal file
10
gravity.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "gravity.h"
|
||||||
|
|
||||||
|
|
||||||
|
double calcul_gravity_object(const double grav, const double masse, const double r){
|
||||||
|
// Newton's law for gravitation
|
||||||
|
return grav * (masse / pow(r, 2));
|
||||||
|
}
|
8
gravity.h
Normal file
8
gravity.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef H_GRAVITY
|
||||||
|
#define H_GRAVITY
|
||||||
|
|
||||||
|
#include "constantes.h"
|
||||||
|
|
||||||
|
double calcul_gravity_object(const double, const double, const double);
|
||||||
|
|
||||||
|
#endif
|
16
gravity.yml
Normal file
16
gravity.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
Constantes:
|
||||||
|
grav: 6.673e-11
|
||||||
|
|
||||||
|
Projectile:
|
||||||
|
x: 0 # Position in x
|
||||||
|
y: 0 # Position in y
|
||||||
|
v0: 10.0 # Initial speed in meter/s
|
||||||
|
angle: 30 # Angle in degree
|
||||||
|
masse: 100 # Masse of projectile
|
||||||
|
height: 20 # Height
|
||||||
|
width: 20 # Width
|
||||||
|
|
||||||
|
Planet1:
|
||||||
|
rayon: 6.371e6 # Rayon earth in meter -> 6371.00 km
|
||||||
|
masse: 5.972e24 # Masse of earth, moon, etc... in kg
|
BIN
main
Executable file
BIN
main
Executable file
Binary file not shown.
132
main.c
Normal file
132
main.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include "argparser.h"
|
||||||
|
#include "yaml.h"
|
||||||
|
#include "gravity.h"
|
||||||
|
#include "motion.h"
|
||||||
|
#include "constantes.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "sdl/projectile.h"
|
||||||
|
|
||||||
|
static void mainInitPlanet(const struct yamlFile *, struct object *, char *, double);
|
||||||
|
static void mainInitProjectile(const struct yamlFile *, struct projectile *, const double);
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int res = -1;
|
||||||
|
int debug = FALSE;
|
||||||
|
FILE *f = NULL;
|
||||||
|
/* Create our structures */
|
||||||
|
struct yamlFile *yamlFile = malloc(sizeof(struct yamlFile));
|
||||||
|
struct constantes constantes;
|
||||||
|
struct object s_planet1;
|
||||||
|
struct projectile s_projectile;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/** CHECK ARGUMENTS **/
|
||||||
|
if (argc == 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = getArgs(argv[1]);
|
||||||
|
|
||||||
|
if (res == FALSE)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
res = fileExist(argv[2]);
|
||||||
|
if (res == -1){
|
||||||
|
printf("File %s doesn't exist\n", argv[2]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if debug */
|
||||||
|
if(argc == 4){
|
||||||
|
if(getArgsOptional(argv[3]) == TRUE){
|
||||||
|
debug = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CONFIGURE VARIABLES **/
|
||||||
|
f = fopen(argv[2], "r");
|
||||||
|
|
||||||
|
// Stock in struct yamlFile the data
|
||||||
|
bufferingFiles(f, yamlFile);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
// Stock constants variables from YAML file
|
||||||
|
/* Get constantes variables */
|
||||||
|
constantes.grav = parseYamlFileDouble(yamlFile, "Constantes:grav");
|
||||||
|
|
||||||
|
// Init planet
|
||||||
|
mainInitPlanet(yamlFile, &s_planet1, "Planet1", constantes.grav);
|
||||||
|
|
||||||
|
// Initialise projectile
|
||||||
|
mainInitProjectile(yamlFile, &s_projectile, s_planet1.grav);
|
||||||
|
|
||||||
|
switch (argv[1][1]){
|
||||||
|
case 'c':
|
||||||
|
handleProjectile(&s_projectile, &s_planet1, debug);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We destroy our multi-array */
|
||||||
|
for(i = 0; i < yamlFile->len; i++)
|
||||||
|
free(yamlFile->buf[i]);
|
||||||
|
free(yamlFile->buf);
|
||||||
|
free(yamlFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void mainInitPlanet(const struct yamlFile *yamlFile, struct object *s_planet, char *p, double grav){
|
||||||
|
/* Initialise caracteristique of planet */
|
||||||
|
char rayon[BUF_SIZE];
|
||||||
|
char masse[BUF_SIZE];
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
res = sprintf(rayon, "%s:rayon", p);
|
||||||
|
if(res < 0){
|
||||||
|
printf("Failed to initialize planet: %s\n", p);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
res = sprintf(masse, "%s:masse", p);
|
||||||
|
if(res < 0){
|
||||||
|
printf("Failed to initialize planet: %s\n", p);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
s_planet->rayon = parseYamlFileDouble(yamlFile, rayon);
|
||||||
|
s_planet->masse = parseYamlFileDouble(yamlFile, masse);
|
||||||
|
|
||||||
|
// Calcul gravitational force in Newton
|
||||||
|
s_planet->grav = calcul_gravity_object(grav, s_planet->masse, s_planet->rayon);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function initialize projectile's structure
|
||||||
|
*/
|
||||||
|
static void mainInitProjectile(const struct yamlFile *yamlFile, struct projectile *s_projectile, const double grav){
|
||||||
|
double v0 = 0.0;
|
||||||
|
double deg_to_rad = 0.0;
|
||||||
|
s_projectile->height = parseYamlFileInt(yamlFile, "Projectile:height");
|
||||||
|
s_projectile->width= parseYamlFileInt(yamlFile, "Projectile:width");
|
||||||
|
s_projectile->x = parseYamlFileInt(yamlFile, "Projectile:x");
|
||||||
|
s_projectile->y = parseYamlFileInt(yamlFile, "Projectile:y");
|
||||||
|
v0 = parseYamlFileDouble(yamlFile, "Projectile:v0");
|
||||||
|
s_projectile->masse = parseYamlFileInt(yamlFile, "Projectile:masse");
|
||||||
|
s_projectile->alpha = parseYamlFileDouble(yamlFile, "Projectile:angle");
|
||||||
|
deg_to_rad = degree_to_radian(s_projectile->alpha);
|
||||||
|
s_projectile->v0x = calcul_initial_speed(deg_to_rad, v0, 'x');
|
||||||
|
s_projectile->v0y = calcul_initial_speed(deg_to_rad, v0, 'y');
|
||||||
|
s_projectile->rect.x = s_projectile->x;
|
||||||
|
s_projectile->rect.y = s_projectile->y;
|
||||||
|
s_projectile->rect.w = s_projectile->height;
|
||||||
|
s_projectile->rect.h = s_projectile->width;
|
||||||
|
|
||||||
|
/***** Informations about the projectile *****/
|
||||||
|
// Calcul delta t
|
||||||
|
s_projectile->deltat = calcul_delta_t(s_projectile->v0y, grav);
|
||||||
|
|
||||||
|
// calcul distance in meter
|
||||||
|
s_projectile->distance = calcul_distance_total(s_projectile->v0x, s_projectile->deltat);
|
||||||
|
|
||||||
|
// Calcul height Max
|
||||||
|
s_projectile->hmax = calcul_height_max(0.0, s_projectile->v0y, grav);
|
||||||
|
}
|
35
motion.c
Normal file
35
motion.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "motion.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
double calcul_initial_speed(double alpha, double speed, const char c) {
|
||||||
|
// We calculated the v0 of y
|
||||||
|
if (c == 'x')
|
||||||
|
return speed * cos(alpha);
|
||||||
|
// Otherwise, we calculated the v0 of x
|
||||||
|
else
|
||||||
|
return speed * sin(alpha);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function calcul the during of the time before the projectile have touche the ground
|
||||||
|
*/
|
||||||
|
double calcul_delta_t(double v, double grav){
|
||||||
|
return (2 * v) / grav;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function calcul the distance total of the projectile
|
||||||
|
*/
|
||||||
|
double calcul_distance_total(double v, double deltat){
|
||||||
|
return v * deltat;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function calcul the height max of the Projectile
|
||||||
|
*/
|
||||||
|
double calcul_height_max(double vx, double vy, double grav){
|
||||||
|
return (pow(vx, 2) - pow(vy, 2)) / (2 * -grav);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function convert the degree in radian
|
||||||
|
*/
|
||||||
|
double degree_to_radian(double degree){
|
||||||
|
return degree * M_PI / 180;
|
||||||
|
}
|
10
motion.h
Normal file
10
motion.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef H_MOTION
|
||||||
|
#define H_MOTION
|
||||||
|
|
||||||
|
double calcul_initial_speed(double, double, const char);
|
||||||
|
double calcul_delta_t(double, double);
|
||||||
|
double calcul_distance_total(double, double);
|
||||||
|
double calcul_height_max(double, double, double);
|
||||||
|
double degree_to_radian(double);
|
||||||
|
|
||||||
|
#endif
|
BIN
sdl/fonts/FreeSans.otf
Normal file
BIN
sdl/fonts/FreeSans.otf
Normal file
Binary file not shown.
BIN
sdl/imgs/projectile.png
Normal file
BIN
sdl/imgs/projectile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 624 B |
62
sdl/imgs/projectile.svg
Normal file
62
sdl/imgs/projectile.svg
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
viewBox="0 0 210 297"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
|
sodipodi:docname="circle.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="370.13101"
|
||||||
|
inkscape:cy="596.73052"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Calque 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<circle
|
||||||
|
id="path12"
|
||||||
|
cx="54.200203"
|
||||||
|
cy="116.38132"
|
||||||
|
style="fill:#ff0000;stroke-width:0.13229166"
|
||||||
|
r="5" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
56
sdl/init_sdl.c
Normal file
56
sdl/init_sdl.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "init_sdl.h"
|
||||||
|
|
||||||
|
void initWindow(SDL_Window **win, TTF_Font **font, char *t, int h, int w){
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO) != 0){
|
||||||
|
printf("SDL: Failed to init sdl: %s\n", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//SDL_Window *win;
|
||||||
|
*win = SDL_CreateWindow(t, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
w, h,
|
||||||
|
SDL_WINDOW_SHOWN);
|
||||||
|
|
||||||
|
/* Init TTF */
|
||||||
|
if(TTF_Init() != 0){
|
||||||
|
printf("SDL: Failed to init TTF: %s\n", SDL_GetError());
|
||||||
|
SDL_Quit();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*font = TTF_OpenFont("sdl/fonts/FreeSans.otf", 25);
|
||||||
|
|
||||||
|
if(*win == NULL){
|
||||||
|
printf("SDL: Failed to init SDL\n");
|
||||||
|
TTF_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*font == NULL){
|
||||||
|
printf("SDL: Failed to open font\n");
|
||||||
|
SDL_DestroyWindow(*win);
|
||||||
|
TTF_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_Surface *loadImage(const char *filename){
|
||||||
|
SDL_Surface *s = IMG_Load(filename);
|
||||||
|
if(s == NULL) {
|
||||||
|
printf("SDL: Failed to load img\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
void destroyWindow(SDL_Window *w, SDL_Renderer *r, TTF_Font *f){
|
||||||
|
if (f != NULL)
|
||||||
|
TTF_CloseFont(f);
|
||||||
|
if (r != NULL)
|
||||||
|
SDL_DestroyRenderer(r);
|
||||||
|
if (w != NULL)
|
||||||
|
SDL_DestroyWindow(w);
|
||||||
|
TTF_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
20
sdl/init_sdl.h
Normal file
20
sdl/init_sdl.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef H_INITSDL
|
||||||
|
#define H_INITSDL
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
|
struct window{
|
||||||
|
SDL_Window *win;
|
||||||
|
TTF_Font *font;
|
||||||
|
SDL_Renderer *r;
|
||||||
|
int h;
|
||||||
|
int w;
|
||||||
|
};
|
||||||
|
|
||||||
|
void initWindow(SDL_Window **, TTF_Font **, char *, int, int);
|
||||||
|
SDL_Surface *loadImage(const char *);
|
||||||
|
void destroyWindow(SDL_Window *, SDL_Renderer*, TTF_Font*);
|
||||||
|
|
||||||
|
#endif
|
241
sdl/projectile.c
Normal file
241
sdl/projectile.c
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "projectile.h"
|
||||||
|
|
||||||
|
/* State of projectile */
|
||||||
|
int isLaunch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function initialize our Projectile
|
||||||
|
*/
|
||||||
|
static void initProjectile(struct window *s_w, struct projectile *s_p){
|
||||||
|
s_w->r = SDL_CreateRenderer(s_w->win, -1, 0);
|
||||||
|
if(s_w->r == NULL){
|
||||||
|
printf("Failed to create renderer\n");
|
||||||
|
destroyWindow(s_w->win, s_w->r, s_w->font);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
s_p->s = loadImage("sdl/imgs/projectile.png");
|
||||||
|
if(s_p->s == NULL){
|
||||||
|
destroyWindow(s_w->win, s_w->r, s_w->font);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
s_p->t = SDL_CreateTextureFromSurface(s_w->r, s_p->s);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function init our rect for drawing Informations on the projectile
|
||||||
|
*/
|
||||||
|
static void initInfos(TTF_Font *font, SDL_Rect *r, const SDL_Surface *s, int x, int y){
|
||||||
|
r->w = s->w;
|
||||||
|
r->h = s->h;
|
||||||
|
r->x = x;
|
||||||
|
r->y = y;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function draw an celestial object, for instance a planet
|
||||||
|
*/
|
||||||
|
static void drawCelestialObject(const struct window window, const SDL_Rect rectObject){
|
||||||
|
// Draw celestial object
|
||||||
|
SDL_SetRenderDrawColor(window.r, 55, 27, 7, 255);
|
||||||
|
SDL_RenderFillRect(window.r, &rectObject);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function draw a text from SDL_Surface *surface in window
|
||||||
|
*/
|
||||||
|
static void drawText(const struct window window, const SDL_Rect rect, SDL_Surface *surface){
|
||||||
|
SDL_Texture *tFont = SDL_CreateTextureFromSurface(window.r, surface);
|
||||||
|
|
||||||
|
SDL_RenderCopy(window.r, tFont, NULL, &rect);
|
||||||
|
|
||||||
|
SDL_DestroyTexture(tFont);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function draw all objects in our screen
|
||||||
|
*/
|
||||||
|
static void drawObjects(const struct window window, const struct projectile *s_projectile, const SDL_Rect rectObject, const SDL_Rect *rectInfos, SDL_Surface **sInfos){
|
||||||
|
/* Draw screen */
|
||||||
|
SDL_SetRenderDrawColor(window.r, 0, 0, 0, 255);
|
||||||
|
SDL_RenderClear(window.r);
|
||||||
|
|
||||||
|
/* Draw grid */
|
||||||
|
drawGrid(window);
|
||||||
|
|
||||||
|
// Draw celestial object
|
||||||
|
drawCelestialObject(window, rectObject);
|
||||||
|
drawText(window, *rectInfos, *sInfos);
|
||||||
|
|
||||||
|
// Draw infos
|
||||||
|
drawText(window, *(rectInfos + 1), *(sInfos + 1));
|
||||||
|
drawText(window, *(rectInfos + 2), *(sInfos + 2));
|
||||||
|
drawText(window, *(rectInfos + 3), *(sInfos + 3));
|
||||||
|
|
||||||
|
// Draw balle
|
||||||
|
SDL_RenderCopy(window.r, s_projectile->t, NULL, &s_projectile->rect);
|
||||||
|
SDL_RenderPresent(window.r);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function draw a grid in window
|
||||||
|
*/
|
||||||
|
static void drawGrid(const struct window window){
|
||||||
|
int i;
|
||||||
|
int scale = SCALE * 5;
|
||||||
|
SDL_SetRenderDrawColor(window.r, 83, 83, 83, 255);
|
||||||
|
|
||||||
|
// Draw vertical lines
|
||||||
|
for (i = 0; i < window.w; i = i + scale)
|
||||||
|
SDL_RenderDrawLine(window.r, i, 0, i, window.h);
|
||||||
|
|
||||||
|
// Draw horizontal lines
|
||||||
|
for (i = 0; i < window.h; i = i + scale)
|
||||||
|
SDL_RenderDrawLine(window.r, 0, i, window.w, i);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function execute the thread
|
||||||
|
*/
|
||||||
|
static int run(void *args){
|
||||||
|
int i = 0;
|
||||||
|
struct thread_projectile_args *arg = (struct thread_projectile_args*)args;
|
||||||
|
double v0x = arg->projectile->v0x * SCALE;
|
||||||
|
double v0y = arg->projectile->v0y * SCALE;
|
||||||
|
double x0 = arg->projectile->x;
|
||||||
|
double y0;
|
||||||
|
SDL_Rect rectObject = arg->rectObject;
|
||||||
|
SDL_Rect *rectInfos = arg->rectInfos;
|
||||||
|
SDL_Surface **sInfos = arg->sInfos;
|
||||||
|
|
||||||
|
/* Position projectile in altitude */
|
||||||
|
arg->projectile->rect.y = rectObject.y + (-arg->projectile->y) - arg->projectile->width;
|
||||||
|
y0 = arg->projectile->rect.y;
|
||||||
|
arg->projectile->rect.x = arg->projectile->x - (arg->projectile->width / 2);
|
||||||
|
x0 = arg->projectile->rect.x;
|
||||||
|
|
||||||
|
/* Draw projectile */
|
||||||
|
drawObjects(arg->window, arg->projectile, rectObject, rectInfos, sInfos);
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
while(isLaunch != LANDING && isLaunch != STOP) {
|
||||||
|
int res = y0 - ((v0y * i) - arg->planet->grav * (i * i));
|
||||||
|
|
||||||
|
if((res + arg->projectile->height) > rectObject.y){
|
||||||
|
arg->projectile->rect.y = rectObject.y - arg->projectile->height;
|
||||||
|
isLaunch = LANDING;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
arg->projectile->rect.x = x0 + v0x * i;
|
||||||
|
arg->projectile->rect.y = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawObjects(arg->window, arg->projectile, rectObject, rectInfos, sInfos);
|
||||||
|
|
||||||
|
SDL_Delay(50);
|
||||||
|
if(arg->debug == TRUE)
|
||||||
|
printf("x: %d y:%d\n", arg->projectile->rect.x, arg->projectile->rect.y);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This is main function, init our objects and create a thread
|
||||||
|
*/
|
||||||
|
void handleProjectile(struct projectile *s_projectile, const struct object *s_planet, int debug){
|
||||||
|
SDL_Event event;
|
||||||
|
SDL_Thread *sthread;
|
||||||
|
static struct thread_projectile_args args;
|
||||||
|
SDL_Rect rectObject;
|
||||||
|
SDL_Rect rectInfos[4];
|
||||||
|
SDL_Surface *sInfos[4];
|
||||||
|
SDL_Color colorFont = {255, 255, 255};
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
int done = 1;
|
||||||
|
struct window s_window;
|
||||||
|
s_window.h = WIN_PROJECTILE_HEIGHT;
|
||||||
|
s_window.w = WIN_PROJECTILE_WIDTH;
|
||||||
|
|
||||||
|
args.projectile = s_projectile;
|
||||||
|
args.planet = s_planet;
|
||||||
|
args.debug = debug;
|
||||||
|
|
||||||
|
// Init celestial object
|
||||||
|
rectObject.x = 0;
|
||||||
|
rectObject.y = WIN_PROJECTILE_HEIGHT - (WIN_PROJECTILE_HEIGHT / 5);
|
||||||
|
rectObject.h = WIN_PROJECTILE_HEIGHT - 200;
|
||||||
|
rectObject.w = WIN_PROJECTILE_WIDTH;
|
||||||
|
args.rectObject = rectObject;
|
||||||
|
|
||||||
|
// Init Video
|
||||||
|
initWindow(&s_window.win, &s_window.font, "Projectile simulator", s_window.h, s_window.w);
|
||||||
|
|
||||||
|
// Init projectile
|
||||||
|
initProjectile(&s_window, s_projectile);
|
||||||
|
args.window = s_window;
|
||||||
|
|
||||||
|
/* Init celestial object */
|
||||||
|
*sInfos = TTF_RenderText_Blended(s_window.font, "Earth", colorFont);
|
||||||
|
initInfos(s_window.font, &rectInfos[0], sInfos[0], (WIN_PROJECTILE_WIDTH / 2) - sInfos[0]->w, rectObject.y + 15);
|
||||||
|
|
||||||
|
/* Get distance and time */
|
||||||
|
sprintf(buf, "Distance: %f m", s_projectile->distance);
|
||||||
|
*(sInfos + 1) = TTF_RenderText_Blended(s_window.font, buf, colorFont);
|
||||||
|
initInfos(s_window.font, &rectInfos[1], sInfos[1], 10, rectInfos[0].y + 20);
|
||||||
|
|
||||||
|
memset(buf, 0, BUF_SIZE);
|
||||||
|
sprintf(buf, "Time: %f s", s_projectile->deltat);
|
||||||
|
*(sInfos + 2) = TTF_RenderText_Blended(s_window.font, buf, colorFont);
|
||||||
|
initInfos(s_window.font, &rectInfos[2], sInfos[2], 10, rectInfos[1].y + 30);
|
||||||
|
|
||||||
|
memset(buf, 0, BUF_SIZE);
|
||||||
|
sprintf(buf, "Height max: %f m", s_projectile->hmax);
|
||||||
|
*(sInfos + 3) = TTF_RenderText_Blended(s_window.font, buf, colorFont);
|
||||||
|
initInfos(s_window.font, &rectInfos[3], sInfos[3], 10, rectInfos[2].y + 30);
|
||||||
|
|
||||||
|
args.rectInfos = rectInfos;
|
||||||
|
args.sInfos = sInfos;
|
||||||
|
|
||||||
|
// Create our thread
|
||||||
|
isLaunch = STOP;
|
||||||
|
sthread = SDL_CreateThread(run, "Projectile", (void*)&args);
|
||||||
|
|
||||||
|
if(sthread == NULL){
|
||||||
|
printf("SDL_CreateThread failed: %s\n", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(done){
|
||||||
|
SDL_WaitEvent(&event);
|
||||||
|
switch(event.type){
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
switch(event.key.keysym.sym){
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
done = 0;
|
||||||
|
break;
|
||||||
|
case SDLK_RETURN:
|
||||||
|
// launch the projectile
|
||||||
|
isLaunch = LAUNCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FreeSurface(sInfos[0]);
|
||||||
|
SDL_FreeSurface(sInfos[1]);
|
||||||
|
SDL_FreeSurface(sInfos[2]);
|
||||||
|
SDL_FreeSurface(sInfos[3]);
|
||||||
|
|
||||||
|
cleanProjectile(&s_window, s_projectile);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function clean our projectile object
|
||||||
|
*/
|
||||||
|
static void cleanProjectile(struct window *s_window, struct projectile *p){
|
||||||
|
if(p->t != NULL)
|
||||||
|
SDL_DestroyTexture(p->t);
|
||||||
|
if(p->s != NULL)
|
||||||
|
SDL_FreeSurface(p->s);
|
||||||
|
|
||||||
|
destroyWindow(s_window->win, s_window->r, s_window->font);
|
||||||
|
}
|
57
sdl/projectile.h
Normal file
57
sdl/projectile.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef H_SDL_PROJECTILE
|
||||||
|
#define H_SDL_PROJECTILE
|
||||||
|
|
||||||
|
#include "init_sdl.h"
|
||||||
|
#include "../constantes.h"
|
||||||
|
|
||||||
|
/* Defines for window's size */
|
||||||
|
#define WIN_PROJECTILE_HEIGHT 712
|
||||||
|
#define WIN_PROJECTILE_WIDTH 1024
|
||||||
|
|
||||||
|
#define SCALE 10
|
||||||
|
|
||||||
|
/* Structure used for thread args */
|
||||||
|
struct thread_projectile_args{
|
||||||
|
struct window window;
|
||||||
|
struct projectile *projectile;
|
||||||
|
const struct object *planet;
|
||||||
|
SDL_Rect rectObject;
|
||||||
|
SDL_Rect *rectInfos;
|
||||||
|
SDL_Surface **sInfos;
|
||||||
|
int debug;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct projectile{
|
||||||
|
SDL_Texture *t;
|
||||||
|
SDL_Surface *s;
|
||||||
|
SDL_Rect rect;
|
||||||
|
int x; /* Position in x */
|
||||||
|
int y; /* Position in y */
|
||||||
|
double v0x; /* Vitesse initiale x */
|
||||||
|
double v0y; /* Vitesse initiale y */
|
||||||
|
int masse; /* Projectile's masse */
|
||||||
|
int height;
|
||||||
|
int width;
|
||||||
|
int alpha; /* Angle in degree */
|
||||||
|
double deltat; /* Delta t */
|
||||||
|
double distance; /* Distance */
|
||||||
|
double hmax; /* Max height */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum stateProjectile{
|
||||||
|
LAUNCH = 0,
|
||||||
|
STOP = 1,
|
||||||
|
LANDING = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static void initProjectile(struct window *, struct projectile *);
|
||||||
|
static void initInfos(TTF_Font *, SDL_Rect *, const SDL_Surface *, int, int);
|
||||||
|
static void drawCelestialObject(const struct window, const SDL_Rect);
|
||||||
|
static void drawText(const struct window, const SDL_Rect, SDL_Surface *);
|
||||||
|
static void drawGrid(const struct window);
|
||||||
|
static void drawObjects(const struct window, const struct projectile *, const SDL_Rect, const SDL_Rect*, SDL_Surface**);
|
||||||
|
static int run(void *);
|
||||||
|
void handleProjectile(struct projectile*, const struct object *, int);
|
||||||
|
static void cleanProjectile(struct window *, struct projectile *);
|
||||||
|
|
||||||
|
#endif
|
248
yaml.c
Normal file
248
yaml.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "constantes.h"
|
||||||
|
#include "yaml.h"
|
||||||
|
|
||||||
|
void parseYamlFileVariables(const struct yamlFile *yamlFile, char *entry, char dst[2][BUF_SIZE]){
|
||||||
|
int line, res;
|
||||||
|
char buf[2][BUF_SIZE];
|
||||||
|
char buf_var[2][BUF_SIZE];
|
||||||
|
char section[20];
|
||||||
|
|
||||||
|
/* Get entry and variable name */
|
||||||
|
res = explodeEntry(entry, buf, ':');
|
||||||
|
|
||||||
|
if (res != YAML_SUCCESS) {
|
||||||
|
printf("Failed to parse YAML's file\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seek section in yaml */
|
||||||
|
res = addDoublePoint(buf[0], section);
|
||||||
|
line = getPositionSection(yamlFile, section);
|
||||||
|
if (line == -1){
|
||||||
|
printf("Failed to find section %s in YAML's file\n", buf[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get variables */
|
||||||
|
res = getVariables(yamlFile, buf[1], buf_var, line);
|
||||||
|
if (res == VARIABLE_YAML_NOT_FOUND){
|
||||||
|
printf("Variable %s not found in YAML's file\n", buf[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
strcpy(dst[0], buf_var[0]);
|
||||||
|
strcpy(dst[1], buf_var[1]);
|
||||||
|
}
|
||||||
|
void parseYamlFileChar(const struct yamlFile *yamlFile, char *entry, char *dst) {
|
||||||
|
char buf_var[2][BUF_SIZE];
|
||||||
|
|
||||||
|
/* Get variables */
|
||||||
|
parseYamlFileVariables(yamlFile, entry, buf_var);
|
||||||
|
|
||||||
|
strcpy(dst, buf_var[1]);
|
||||||
|
}
|
||||||
|
double parseYamlFileDouble(const struct yamlFile *yamlFile, char *entry) {
|
||||||
|
char buf[2][BUF_SIZE];
|
||||||
|
char buf_var[2][BUF_SIZE];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/* Get variables */
|
||||||
|
parseYamlFileVariables(yamlFile, entry, buf_var);
|
||||||
|
|
||||||
|
/* Get if pow */
|
||||||
|
res = explodeEntry(buf_var[1], buf, 'e');
|
||||||
|
if (res == YAML_SUCCESS){
|
||||||
|
double d1, d2;
|
||||||
|
d1 = atof(buf[0]);
|
||||||
|
d2 = atof(buf[1]);
|
||||||
|
return d1 * pow(10, d2);
|
||||||
|
}
|
||||||
|
return atof(buf_var[1]);
|
||||||
|
}
|
||||||
|
int parseYamlFileInt(const struct yamlFile *yamlFile, char *entry){
|
||||||
|
char buf[2][BUF_SIZE];
|
||||||
|
char buf_var[2][BUF_SIZE];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/* Get variables */
|
||||||
|
parseYamlFileVariables(yamlFile, entry, buf_var);
|
||||||
|
|
||||||
|
/* Get if pow */
|
||||||
|
res = explodeEntry(buf_var[1], buf, 'e');
|
||||||
|
if (res == YAML_SUCCESS){
|
||||||
|
double d1, d2;
|
||||||
|
d1 = atof(buf[0]);
|
||||||
|
d2 = atof(buf[1]);
|
||||||
|
return d1 * pow(10, d2);
|
||||||
|
}
|
||||||
|
return atoi(buf_var[1]);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function read the YAML's file and stock all data in structure
|
||||||
|
*/
|
||||||
|
struct yamlFile *bufferingFiles(FILE *f, struct yamlFile *yamlFile){
|
||||||
|
char c;
|
||||||
|
char buf_tmp[BUF_SIZE];
|
||||||
|
int i=0, lines=0;
|
||||||
|
|
||||||
|
/* We count the number of lines */
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
do{
|
||||||
|
c = fgetc(f);
|
||||||
|
|
||||||
|
if(c == '\n')
|
||||||
|
lines++;
|
||||||
|
}while (c != EOF);
|
||||||
|
|
||||||
|
yamlFile->len = lines;
|
||||||
|
|
||||||
|
/* We allocate our buffer */
|
||||||
|
if((yamlFile->buf = malloc(lines * sizeof(char*))) == NULL){
|
||||||
|
printf("Failed to malloc\n");
|
||||||
|
fclose(f);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for(i = 0; i < lines; i++)
|
||||||
|
if((yamlFile->buf[i] = malloc(BUF_SIZE)) == NULL){
|
||||||
|
printf("Failed to malloc\n");
|
||||||
|
fclose(f);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
lines = 0;
|
||||||
|
do{
|
||||||
|
c = fgetc(f);
|
||||||
|
|
||||||
|
buf_tmp[i++] = c;
|
||||||
|
if(c == '\n'){
|
||||||
|
buf_tmp[--i] = '\0';
|
||||||
|
memcpy(yamlFile->buf[lines++], buf_tmp, i);
|
||||||
|
memset(buf_tmp, 0, BUF_SIZE);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}while (c != EOF);
|
||||||
|
|
||||||
|
return yamlFile;
|
||||||
|
}
|
||||||
|
int addDoublePoint(char *src, char *dst){
|
||||||
|
int i = 0;
|
||||||
|
while (src[i] != '\0'){
|
||||||
|
dst[i] = src[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dst[i++] = ':';
|
||||||
|
dst[i++] = '\0';
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int readYaml(FILE *f, char *section){
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
char c;
|
||||||
|
int i = 0;
|
||||||
|
int line = 0;
|
||||||
|
int seek = PARSE_YAML_FAILED;
|
||||||
|
/* Seek the section, example gravity: in file */
|
||||||
|
do {
|
||||||
|
c = fgetc(f);
|
||||||
|
buf[i++] = c;
|
||||||
|
if(c == '\n') {
|
||||||
|
buf[--i] = '\0'; /* Remove the '\n' */
|
||||||
|
seek = findEntry(buf, section);
|
||||||
|
if (seek == YAML_SUCCESS) break;
|
||||||
|
/* Get cursor position in file */
|
||||||
|
memset(buf, 0, BUF_SIZE);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
line++;
|
||||||
|
}while(c != EOF);
|
||||||
|
if (seek == PARSE_YAML_FAILED) return seek;
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
int findEntry(char *buf, char *entry) {
|
||||||
|
int seek = PARSE_YAML_FAILED;
|
||||||
|
if (strcmp(buf, entry) == 0) {
|
||||||
|
seek = YAML_SUCCESS;
|
||||||
|
}
|
||||||
|
return seek;
|
||||||
|
}
|
||||||
|
int getVariables(const struct yamlFile *yamlFile, char *variable, char buf_var[2][BUF_SIZE], int posEntry) {
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
char buf2[2][BUF_SIZE];
|
||||||
|
memset(buf2[0], 0, BUF_SIZE);
|
||||||
|
memset(buf2[1], 0, BUF_SIZE);
|
||||||
|
char c;
|
||||||
|
int i = 0, j, pos=0, lines=0;
|
||||||
|
int res = PARSE_YAML_FAILED;
|
||||||
|
|
||||||
|
for(lines = posEntry; lines < yamlFile->len; lines++){
|
||||||
|
do {
|
||||||
|
c = yamlFile->buf[lines][pos++];
|
||||||
|
if (c != ' ')
|
||||||
|
buf[i++] = c;
|
||||||
|
} while(c != '\0');
|
||||||
|
|
||||||
|
/* Seek our variable */
|
||||||
|
if(strlen(buf) > 0){
|
||||||
|
res = explodeEntry(buf, buf_var, ':');
|
||||||
|
if(res == YAML_SUCCESS) {
|
||||||
|
char t[BUF_SIZE];
|
||||||
|
if (buf_var[0][0] == '-'){
|
||||||
|
int x = 0;
|
||||||
|
for(j = 1; j < strlen(buf_var[0]); j++)
|
||||||
|
t[x++] = buf_var[0][j];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(t, buf_var[0]);
|
||||||
|
if(strcmp(t, variable) == 0){
|
||||||
|
res = YAML_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else res = VARIABLE_YAML_NOT_FOUND;
|
||||||
|
memset(t, 0, BUF_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, BUF_SIZE);
|
||||||
|
i = 0;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int explodeEntry(char *entry, char var[2][BUF_SIZE], char delimiter) {
|
||||||
|
char c;
|
||||||
|
int i = 0, j = 0, pos = 0;
|
||||||
|
/* Get position of delimiter */
|
||||||
|
do {
|
||||||
|
c = entry[i];
|
||||||
|
if (c == delimiter) pos = i;
|
||||||
|
i++;
|
||||||
|
}while(c != '\0');
|
||||||
|
if (pos == 0)
|
||||||
|
return YAML_DELIMITER_NOT_FOUND;
|
||||||
|
|
||||||
|
for(i = 0; i < pos; i++) {
|
||||||
|
var[0][i] = entry[i];
|
||||||
|
}
|
||||||
|
var[0][i++] = '\0';
|
||||||
|
for(i = pos + 1, j=0; i < strlen(entry); i++, j++) {
|
||||||
|
var[1][j] = entry[i];
|
||||||
|
}
|
||||||
|
var[1][j++] = '\0';
|
||||||
|
return YAML_SUCCESS;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This function get the position (int) for the section
|
||||||
|
*/
|
||||||
|
int getPositionSection(const struct yamlFile *yamlFile, char *section){
|
||||||
|
int i = 0, pos = -1;
|
||||||
|
|
||||||
|
for(i = 0; i < yamlFile->len; i++){
|
||||||
|
if(strcmp(yamlFile->buf[i], section) == 0)
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
26
yaml.h
Normal file
26
yaml.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef H_YAML
|
||||||
|
#define H_YAML
|
||||||
|
|
||||||
|
#define YAML_SUCCESS 0x00000
|
||||||
|
#define PARSE_YAML_FAILED 0x00001
|
||||||
|
#define VARIABLE_YAML_NOT_FOUND 0x00002
|
||||||
|
#define YAML_DELIMITER_NOT_FOUND 0x00003
|
||||||
|
|
||||||
|
struct yamlFile{
|
||||||
|
char **buf;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
void parseYamlFileVariables(const struct yamlFile *, char *, char dst[2][BUF_SIZE]);
|
||||||
|
double parseYamlFileDouble(const struct yamlFile *, char *);
|
||||||
|
int parseYamlFileInt(const struct yamlFile *, char *);
|
||||||
|
void parseYamlFileChar(const struct yamlFile *, char *, char *);
|
||||||
|
struct yamlFile *bufferingFiles(FILE *, struct yamlFile *);
|
||||||
|
int addDoublePoint(char *, char *);
|
||||||
|
int readYaml(FILE *, char *);
|
||||||
|
int findEntry(char *, char *);
|
||||||
|
int getVariables(const struct yamlFile *, char *, char buf_var[2][BUF_SIZE], int);
|
||||||
|
int explodeEntry(char *, char var[2][BUF_SIZE], char);
|
||||||
|
int getPositionSection(const struct yamlFile *, char *);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user