I'm creating a menu in my game (available when I hit escape on the keyboard)
But the black background created with SDL_Rect and the text aren't showing and I don't understand why.
When I run my program I can change the background images by pressing on the arrows (up, down, left and right), and when I hit esc, i can't do anything until I hit esc another time, and then I can continue changing the background color with the arrows on my keyboard.
Does anybody can help me with this?
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL_image.h>
#include <SDL2/SDL_ttf.h>
#define CHOICEMENU 2
void errorMessage(const char *message);
void errorMessageImg(const char *message);
void errorMessageTtf(const char *message);
int printTextTtf(SDL_Surface* window, TTF_Font* mainFont, const char* text);
int displayMenu(SDL_Surface* window, TTF_Font* font);
int main( int argc, char **argv)
{
//Pointeurs de la SDL :
SDL_Window *window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *image1,*image2, *image3, *image4 = NULL;
SDL_Surface *currentImage = NULL;
SDL_Surface *icon = NULL;
SDL_Renderer *renderer = NULL;
int menu;
int running;
TTF_Init(); //initialisation des textes
TTF_Font *mainFont = NULL;
mainFont = TTF_OpenFont("couriernew.ttf",30);
icon = IMG_Load("img/flask.png");
SDL_SetWindowIcon(window,icon);
if(SDL_Init(SDL_INIT_VIDEO) != 0){ //retourne 0 si Ok
errorMessage("Erreur lors de la creation de la fenêtre et du rendu");
}
window = SDL_CreateWindow("Jeu Antoine et Robin", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
windowSurface = SDL_GetWindowSurface(window);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED |
SDL_RENDERER_PRESENTVSYNC);
//texture = SDL_LoadBMP("ici.bmp");
image1 = SDL_LoadBMP("img/image1.bmp");
if(image1 == NULL){
SDL_DestroyWindow(window);
errorMessage("Impossible de charger l'image 1");
}
image2 = SDL_LoadBMP("img/image2.bmp");
if(image2 == NULL){
SDL_DestroyWindow(window);
errorMessage("Impossible de charger l'image 2");
}
image3 = SDL_LoadBMP("img/image3.bmp");
if(image3 == NULL){
SDL_DestroyWindow(window);
errorMessage("Impossible de charger l'image 3");
}
image4 = SDL_LoadBMP("img/image4.bmp");
if(image4 == NULL){
SDL_DestroyWindow(window);
errorMessage("Impossible de charger l'image 4");
}
currentImage = image1;
int isRunning = 1;
SDL_Event ev;
while(isRunning == 1){
while(SDL_PollEvent(&ev) != 0 ){
if(ev.type == SDL_QUIT){
isRunning = false;
}else if(ev.type == SDL_KEYDOWN){
switch(ev.key.keysym.sym){
case SDLK_UP:
currentImage = image1;
break;
case SDLK_RIGHT:
currentImage = image2;
break;
case SDLK_LEFT:
currentImage = image3;
break;
case SDLK_DOWN:
currentImage = image4;
break;
case SDL_QUIT:
isRunning = 0;
break;
case SDLK_ESCAPE:
menu = displayMenu(windowSurface,mainFont);
if(menu == 1){
isRunning = false;
}
break;
}
}
}
SDL_BlitSurface(currentImage, NULL, windowSurface, NULL);
SDL_UpdateWindowSurface(window);
}
TTF_CloseFont(mainFont);
SDL_FreeSurface(image1);
SDL_FreeSurface(image2);
SDL_FreeSurface(image3);
SDL_FreeSurface(image4);
SDL_DestroyWindow(window);
SDL_FreeSurface(icon);
SDL_DestroyRenderer(renderer);
currentImage = image1 = image2 = image3 = NULL;
window = NULL;
SDL_Quit();
return 0;
}
int displayMenu(SDL_Surface* window, TTF_Font* font){
int x,y; // coordonées de la souris
int i;
int nMenu = CHOICEMENU; //nb de choix
const char* choice[CHOICEMENU] = {"Continuer","Quitter"};
SDL_Surface* menus[CHOICEMENU]; // surface des menus
int selected[CHOICEMENU]={0,0}; // 0 car aucun selectionné pour le moment
SDL_Color colorMenu[2]={{127,122,204},{49,100,226}};
menus[0] = TTF_RenderText_Solid(font, choice[0], colorMenu[0]);
menus[1] = TTF_RenderText_Solid(font, choice[1], colorMenu[1]);
SDL_Rect pos[CHOICEMENU];
pos[0].x = window->clip_rect.w/2 /*= centre */ - menus[0]->clip_rect.w/2;
pos[0].y = window->clip_rect.h/2 - menus[0]->clip_rect.h;
pos[1].x = window->clip_rect.w/2 - menus[0]->clip_rect.w/2;
pos[1].y = window->clip_rect.h/2 + menus[0]->clip_rect.h;
SDL_FillRect(window,&window->clip_rect,SDL_MapRGB(window-
>format,0x00,0x00,0x00));
SDL_Event ev;
while(1){
while(SDL_PollEvent(&ev)){
switch(ev.type){
case SDL_QUIT:
for(i = 0; i < CHOICEMENU ; i++){
SDL_FreeSurface(menus[i]);
}
return 1;
case SDL_MOUSEMOTION: // coordonée souris
x = ev.motion.x;
y = ev.motion.y;
for(i = 0; i < CHOICEMENU; i++){
if(x >= pos[i].x && x<= pos[i].x+pos[i].w && y>=pos[i].y &&
y<=pos[i].y+pos[i].h){
if(!selected[i]){
selected[i] = 1;
SDL_FreeSurface(menus[i]); // on suppr l'ancienne
surface
menus[i] = TTF_RenderText_Solid(font, choice[i],
colorMenu[1]);
} else {
if(selected[i]){
selected[i] = 0;
SDL_FreeSurface(menus[i]); // on suppr
l'ancienne surface
menus[i] = TTF_RenderText_Solid(font, choice[i],
colorMenu[0]);
}
}
}
case SDL_MOUSEBUTTONDOWN: //si qqn a cliquer sur la souris :
x = ev.button.x;
y = ev.button.y;
for (i = 0; i < CHOICEMENU; i+=1){
if(x >= pos[i].x && x<= pos[i].x+pos[i].w && y>=pos[i].y &&
y<=pos[i].y+pos[i].h){
for(i = 0 ;i < CHOICEMENU; i++){
SDL_FreeSurface(menus[i]);
}
return i; // On retourne la valeur actuelle : ex : si je
clique sur "continue" ça return 1
}
}
break;
case SDL_KEYDOWN:
if(ev.key.keysym.sym == SDLK_ESCAPE){
for(i = 0 ;i < CHOICEMENU; i++){
SDL_FreeSurface(menus[i]);
}
return 0;
}
}
}
for(i = 0; i < CHOICEMENU; i+=1){
SDL_BlitSurface(menus[i],NULL,window,&pos[i]);
}
}
}
}
Related
For the creation of the map, the user is left with the possibility of requesting the following four functions via a menu with one (switch):
Insertion of a zone at the end of the insert_zone function list. It creates the new zone in dynamic memory malloc, inserts it in the list by modifying the value of the next_zone pointer of the last land in the list with the result of the malloc. The type of the zone as well as the object found within the zone are randomly generated: all zones are equiprobable, no_object has a 40% probability while the other objects in the enum Object_type_zone have equal probability. Finally, the enum field Tipo_prova prova will be inserted with a certain probability every time a player arrives in a given zone see function advance .
Delete the last zone inserted in the path cancel_zone
Print the fields of all the zones created up to that moment print_map.
i leaves the possibility to the user to use a menu to perform the following four functions:
insert_zone: delete_zone: print_map;
.
I leave a copy of the file.h (works well); "you can help to find the solution for the problem"
#ifndef H_GAMELIB
#define H_GAMELIB
extern void imposta_gioco();
extern void gioca();
extern void termina_gioco();
extern void inserisci_zona();
extern void stampa_mappa();
extern void chiudi_mappa();
extern void cancella_zona();
enum Tipo_Difficolta { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };
struct Zona_mappa {
enum Tipo_zona zona;
enum Tipo_prova prova;
enum Tipo_oggetto_zona oggetto_zona;
struct Zona_mappa* prossima_zona;
};
struct Giocatore {
char nome_giocatore[30];
unsigned char sanita_mentale;
struct Zona_mappa* posizione;
unsigned char zaino[4];
};
#endif
main.c
#include "gamelib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
int main (void){
unsigned short numero;
int c = 0;
printf("\033[1;35m ____ ____ ____ ____ ____ ____ ____ ____ \n");
printf(" ||P |||h |||a |||l |||s |||o |||P |||h ||\n");
printf(" ||__|||__|||__|||__|||__|||__|||__|||__||\n");
printf(" |/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|\n");
printf("\033[0m\n");
printf("||preme 'invio' per continuare||\n");
while(getchar()!= '\n');
do{
printf("\n");
printf("> \033[1;93m1\033[1m: Imposta Gioco.\n");
printf("> \033[1;96m2\033[2m: Gioca.\n");
printf("> \033[1;91m3\033[3m: Termina gioco.\n\n");
printf ("\033[92mScelta:\033[0m ");
scanf("%hu",&numero);
while ((c = getchar()) != '\n' && c != EOF); //pulizia dei buffer
switch(numero){
case 1:
printf("hai inserito il primo numero\n");
imposta_gioco();
break;
case 2:
printf("hai inserito il secondo numero\n");
gioca();break;
case 3:
printf("hai inserito il terzo numero");
termina_gioco();break;
default: printf("\033[31mAttenzione!\033[0m Opzione non valida, per favore inserisci \033[31mun numero da 1 a 3\033[0m.\n");
}
}while (numero != 3);
return 0;
}
gamelib.c
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include "gamelib.h"
#define ERROR_ARGS_NUM(_min, _max) printf("\033[31mAttenzione!\033[5m Opzione non valida, per favore inserisci \033[31mun numero da " #_min " a " #_max "\033[0m.\n")
#define CHECK_NUM_INPUT_RANGE(n, _min, _max)
struct Zona_mappa *pLast = NULL;
struct Zona_mappa *pFirst = NULL;
static struct Giocatore players[4];
static int nplayers = 0;
static int difficulty_level;
int ask_num(const char *prompt)
{
if (prompt)
printf("%s", prompt);
int n;
if (scanf("%d", &n) <= 0)
n = -1;
return n;
}
void mostra_zaino(struct Giocatore *giocatore)
{
const char *nome_oggetto_iniziale;
switch (giocatore->zaino[0])
{
case EMF:
nome_oggetto_iniziale = "EMF";
break;
case spirit_box:
nome_oggetto_iniziale = "Spirit Box";
break;
case videocamera:
nome_oggetto_iniziale = "Videocamera";
break;
case calmanti:
nome_oggetto_iniziale = "Calmanti";
break;
case sale:
nome_oggetto_iniziale = "Sale";
break;
default:
return;
}
printf("Contenuto zaino di %s:\nOggetto iniziale: %s\n", giocatore->nome_giocatore, nome_oggetto_iniziale);
for (int i = 1; i < 3; i++)
{
switch (giocatore->zaino[i])
{
case cento_dollari:
printf("100$\n");
break;
case nessun_oggetto:
printf("nessun_oggetto\n");
break;
case coltello:
printf("coltello\n");
break;
case calmanti1:
printf("calmanti1\n");
break;
case adrenalina:
printf("adrenalina\n");
break;
}
}
printf("\n");
}
void imposta_gioco()
{
srand(time(NULL));
memset(players, 0, sizeof(players));
nplayers = ask_num("Inserisci il numero di giocatori (da 1 a 4): ");
CHECK_NUM_INPUT_RANGE(nplayers, 1, 4);
printf("Scegli il livello di difficoltà:\n");
printf("> \033[1;93m1\033[0m: Dilettante\n");
printf("> \033[2;93m2\033[0m: Intermedio\n");
printf("> \033[3;93m3\033[0m: Incubo\n");
difficulty_level = ask_num("\033[32mInserisci il numero corrispondente: ");
CHECK_NUM_INPUT_RANGE(difficulty_level, 1, 3);
for (int i = 0; i < nplayers; i++)
{
printf("Inserisci il nome del giocatore %d: ", (i + 1));
if (scanf("%s", players[i].nome_giocatore) <= 0)
return;
players[i].sanita_mentale = 100;
players[i].zaino[0] = rand() % 5;
for (int j = 1; j < 4; j++)
players[i].zaino[j] = nessun_oggetto;
mostra_zaino(&players[i]);
}
}
struct Zona_mappa *genera_mappa()
{
// Crea la prima zona mappa
struct Zona_mappa *prima_zona = malloc(sizeof(struct Zona_mappa));
prima_zona->zona = cucina;
// Crea la seconda zona mappa
struct Zona_mappa *seconda_zona = malloc(sizeof(struct Zona_mappa));
seconda_zona->zona = soggiorno;
prima_zona->prossima_zona = seconda_zona;
// Crea la terza zona
struct Zona_mappa *terza_zona = malloc(sizeof(struct Zona_mappa));
terza_zona->zona = garage;
seconda_zona->prossima_zona = terza_zona;
struct Zona_mappa *quarta_zona = malloc(sizeof(struct Zona_mappa));
quarta_zona->zona = camera;
terza_zona->prossima_zona = quarta_zona;
// Crea la terza zona
struct Zona_mappa *quinta_zona = malloc(sizeof(struct Zona_mappa));
quinta_zona->zona = bagno;
quarta_zona->prossima_zona = quinta_zona;
struct Zona_mappa *ultima_zona = malloc(sizeof(struct Zona_mappa));
ultima_zona->zona = seminterrato;
quinta_zona->prossima_zona = ultima_zona;
ultima_zona->prossima_zona = prima_zona;
// Assegna i valori ai puntatori globali
pFirst = prima_zona;
pLast = ultima_zona;
printf("la lista è pronta\n");
return prima_zona; // Restituisce l'indirizzo della prima zona
}
void inserisci_zona()
{
struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
return;
}
nuova_zona->zona = rand() % 4;
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 60)
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 90)
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
}
void cancella_zona()
{
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the last zone in the list and delete it
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = pFirst;
}
void stampa_mappa()
{
// Caso particolare: la lista è vuota
if (pFirst == NULL)
{
printf("La mappa è vuota\n");
return;
}
printf("Stampa della mappa:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != pFirst);
}
void chiudi_mappa()
{
gioco_impostato = 1;
}
// Funzione che avvia il gioco
void gioca()
{
{
}
}
// Funzione che termina il gioco
void termina_gioco()
{
}
I have problems in the following 3 blocks of code
void inserisci_zona()
{
struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
return;
}
nuova_zona->zona = rand() % 4;
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 60)
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 90)
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
}
void cancella_zona()
{
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the last zone in the list and delete it
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = pFirst;
}
void stampa_mappa()
{
// Caso particolare: la lista è vuota
if (pFirst == NULL)
{
printf("La mappa è vuota\n");
return;
}
printf("Stampa della mappa:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != pFirst);
}
Here's the fixed code. Required modifications to fix the code are marked and explained with comments at the end of the lines starting with "// Edit:". It is a single file where I inserted the header file. At the end is a small main() to test the code.
#include <stdlib.h>
#include <stdio.h>
#ifndef H_GAMELIB
#define H_GAMELIB
void imposta_gioco (void);
void gioca (void);
void termina_gioco (void);
void inserisci_zona(void);
void stampa_mappa (void);
void chiudi_mappa (void);
void cancella_zona (void);
enum Tipo_Difficolta { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };
struct Zona_mappa {
enum Tipo_zona zona;
enum Tipo_prova prova;
enum Tipo_oggetto_zona oggetto_zona;
struct Zona_mappa* prossima_zona;
};
struct Giocatore {
char nome_giocatore[30];
unsigned char sanita_mentale;
struct Zona_mappa* posizione;
unsigned char zaino[4];
};
#endif
static struct Zona_mappa* pFirst = NULL; // Edit: Added since pFirst was missing
static struct Zona_mappa* pLast = NULL; // Edit: Added since pLast was missing
void inserisci_zona(void) {
struct Zona_mappa* nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERROR of memory allocation for the new zone\n");
return;
}
nuova_zona->zona = rand() % 7; // Edit: enum has 7 enumerators
// Edit: Since zones are equiprobable, above line is sufficient
/*
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
*/
int r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 55) // Edit: No object has 40% and all others 15%
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 85) // Edit: No object has 40% and all others 15%
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{
// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
}
}
void cancella_zona(void) {
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the second to last zone in the list
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = NULL; // Edit: Next of last zone has to be NULL
}
void stampa_mappa(void) {
// Special case: the list is empty
if (pFirst == NULL)
{
printf("The map is empty\n");
return;
}
printf("Map printing:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zone of type %d, with object %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != NULL); // Edit: Iterate until there's no next Zona_mappa which is the case if next is NULL
}
int main(void) {
stampa_mappa();
inserisci_zona();
inserisci_zona();
inserisci_zona();
stampa_mappa();
cancella_zona();
stampa_mappa();
cancella_zona();
cancella_zona();
stampa_mappa();
for (;;);
return 0;
}
I have been working on a game that is a Stacker. Everything works fine, but after you have played and started over the blocks from the previous game still remain there.
Could anyone help me with this problem?
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
#include <stdio.h>
#include <stdlib.h>
#define BASE_TIME_INTERVAL 80
#define SPEED_INCREASE 1.03
#define GAME_ROWS 15
#define GAME_COLUMNS 7
#define MIN(a, b) ((a < b) ? a : b)
#define MAX(a, b) ((a > b) ? a : b)
int array_matrix[GAME_ROWS][GAME_COLUMNS];
//void save();
int credit = 0;
int in = 0;
int out = 0;
int inGame = 0;
static SDL_Surface *screen;
//Sprites
static SDL_Surface *square;
static SDL_Surface *background;
static SDL_Surface *grid;
static SDL_Surface *main_ui;
static SDL_Surface *award;
//Text Credits Sprites
static SDL_Surface *credits;
static SDL_Surface *number;
//Sounds
Mix_Chunk *soundPlace = NULL;
Mix_Chunk *soundGameOver = NULL;
Mix_Chunk *soundCredit = NULL;
FILE * fptr;
void print_board() {
int i, j;
SDL_Rect src, dest;
for (i = 0; i < 15; i++) {
for (j = 0; j < 7 ; j++) {
if (array_matrix[i][j] == 1) {
src.x = 0;
src.y = 0;
src.w = 65;
src.h = 65;
dest.x = j * 67 + 227;
dest.y = i * 67 + 240;
dest.w = 65;
dest.h = 65;
SDL_BlitSurface(square, &src, screen, &dest);
}
}
}
}
void update_board(int x_pos, int length, int level) {
int underflow_ammt = length - 1;
int j;
if (x_pos < underflow_ammt)
length = length - (underflow_ammt - x_pos);
x_pos = MAX(0, x_pos-underflow_ammt);
for (j = 0; j < GAME_COLUMNS; j++)
array_matrix[GAME_ROWS - level][j] = 0;
for (j = x_pos; j < x_pos + length; j++) {
array_matrix[GAME_ROWS - level][MIN(j, GAME_COLUMNS-1)] = 1;
}
}
int get_new_length(int level) {
int i;
int length = 0;
for (i = 0; i < GAME_COLUMNS; i++) {
if (array_matrix[GAME_ROWS - level][i] == 1) {
length++;
if (level != 1) {
if (array_matrix[GAME_ROWS - (level - 1)][i] != 1) {
array_matrix[GAME_ROWS - level][i] = 0;
length--;
}
}
}
if ((level == 4 && length == 3) || (level == 10 && length == 2)) {
length--;
}
}
return length;
}
void draw_background(){
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(main_ui, NULL, screen, NULL);
SDL_BlitSurface(award, NULL, screen, NULL);
SDL_BlitSurface(grid, NULL, screen, NULL);
}
void draw_credits(){
SDL_Rect destCredits;
SDL_Rect destNumber;
switch (credit)
{
case 0:
number = IMG_Load("assets/0.png");
break;
case 1:
number = IMG_Load("assets/1.png");
break;
case 2:
number = IMG_Load("assets/2.png");
break;
case 3:
number = IMG_Load("assets/3.png");
break;
case 4:
number = IMG_Load("assets/4.png");
break;
case 5:
number = IMG_Load("assets/5.png");
break;
case 6:
number = IMG_Load("assets/6.png");
break;
case 7:
number = IMG_Load("assets/7.png");
break;
case 8:
number = IMG_Load("assets/8.png");
break;
case 9:
number = IMG_Load("assets/9.png");
break;
}
if (number == NULL) {
printf("Unable to load number png.\n");
}
destCredits.x = 300;
destCredits.y = 1300;
destNumber.x = 550;
destNumber.y = 1305;
SDL_BlitSurface(credits, NULL, screen, &destCredits);
SDL_BlitSurface(number, NULL, screen, &destNumber);
}
void game_loop() {
int time_delay = BASE_TIME_INTERVAL;
int left_or_right = 1;
int current_level = 1;
int length = 3;
int x_pos = 0;
int quit = 0;
int underflow_ammt = length - 1;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_SPACE && inGame == 1) {
length = get_new_length(current_level);
underflow_ammt = length - 1;
if (current_level >= 15 || length == 0) {
Mix_PlayChannel( -1, soundGameOver, 0 );
inGame = 0;
time_delay = BASE_TIME_INTERVAL;
left_or_right = 1;
current_level = 1;
length = 3;
x_pos = 0;
underflow_ammt = length - 1;
}
else{
Mix_PlayChannel( -1, soundPlace, 0 );
current_level++;
time_delay = time_delay/SPEED_INCREASE;
}
}
if (event.key.keysym.sym == SDLK_2 && credit < 9){
credit++;
in++;
save();
Mix_PlayChannel( -1, soundCredit, 0 );
}
if (event.key.keysym.sym == SDLK_1 && credit > 0 && inGame == 0){
credit--;
out++;
save();
Mix_PlayChannel( -1, soundCredit, 0 );
inGame = 1;
}
if (event.key.keysym.sym == SDLK_ESCAPE){
quit = 1;
exit(0);
}
break;
case SDL_QUIT:
quit = 1;
exit(0);
break;
}
}
if (!quit) {
SDL_FillRect(screen, NULL, 0x000000);
if (x_pos >= GAME_COLUMNS + (underflow_ammt - 1))
left_or_right = -1;
if (x_pos <= 0)
left_or_right = 1;
update_board(x_pos, length, current_level);
draw_background();
if (inGame == 1)
print_board();
draw_credits();
SDL_Flip(screen);
x_pos = x_pos + left_or_right;
SDL_Delay(time_delay);
}
}
}
/*
void save(){
fptr = fopen("data.xml", "w");
fprintf(fptr,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
fprintf(fptr,"<Data>\n");
fprintf(fptr," <credits>%d</credits>\n",credit);
fprintf(fptr," <IN>%d</IN>\n",in);
fprintf(fptr," <OUT>%d</OUT>\n",out);
fprintf(fptr,"</Data>\n");
fclose(fptr);
}
*/
void init(){
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
}
screen = SDL_SetVideoMode(768, 1366, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_FULLSCREEN);
if (screen == NULL) {
printf("Unable to set video mode: %s\n", SDL_GetError());
}
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
}
if (SDL_Init(SDL_INIT_AUDIO) < 0){
printf("Unable to set audio mode: %s\n", SDL_GetError());
}
//Initialize SDL_mixer
if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) < 0 )
printf( "SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError());
}
void loadMedia(){
background = IMG_Load("assets/background.png");
if (background == NULL)
printf("Unable to load background png.\n");
square = IMG_Load("assets/square.png");
if (square == NULL)
printf("Unable to load square png.\n");
credits = IMG_Load("assets/credits.png");
if (credits == NULL)
printf("Unable to load credits png.\n");
grid = IMG_Load("assets/grid.png");
if (grid == NULL)
printf("Unable to load grid png.\n");
main_ui = IMG_Load("assets/main_ui.png");
if (main_ui == NULL)
printf("Unable to load main_ui png.\n");
soundPlace = Mix_LoadWAV("assets/place.wav");
if(soundPlace == NULL)
printf( "Failed to load place sound effect! SDL_mixer Error: %s\n", Mix_GetError() );
soundGameOver = Mix_LoadWAV("assets/gameover.wav");
if(soundGameOver == NULL)
printf( "Failed to load gameover sound effect! SDL_mixer Error: %s\n", Mix_GetError() );
soundCredit = Mix_LoadWAV("assets/credit.wav");
if( soundCredit == NULL )
printf( "Failed to load credit sound effect! SDL_mixer Error: %s\n", Mix_GetError() );
}
void close(){
SDL_FreeSurface(square);
SDL_FreeSurface(background);
SDL_FreeSurface(credits);
SDL_FreeSurface(grid);
SDL_FreeSurface(main_ui);
SDL_FreeSurface(number);
Mix_FreeChunk(soundPlace);
Mix_FreeChunk(soundGameOver);
Mix_FreeChunk(soundCredit);
Mix_Quit();
IMG_Quit();
SDL_Quit();
}
int main(int argc, char *argv[])
{
init();
loadMedia();
game_loop();
close();
return 0;
}
I using:
SDL 1.2.15
SDL_image 1.2.12
SDL_mixer 1.2.12
My SDL Window displays a bitmap on top of another bitmap however I am not able to control the bitmap image using SDL_KeyDown events. The only event that works is SDL_QUIT.
I attempted to map using the ASWD keys and the Up Down Left and Right arrow keys, however the SDL Window doesn't process any of those events. The only event that occurs is when I click the X button to close the window or when I press the q or escape keys to close the window. Also, none of the printf statements are appearing on the console so I am not sure exactly where the problem is because the program compiles and runs without any errors.
I am using C not C++
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_timer.h>
#include <SDL_image.h>
#define WINDOW_WIDTH (640)
#define WINDOW_HEIGHT (480)
// Speed in Pixels/Seconds
#define SCROLL_SPEED (300)
// Spirte Size
#define SPRITE_SIZE 32
int main(int argc, const char * argv[]) {
// Attempt to initialize graphics library
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return 1;
}
//Initialize Key Variables
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *imageSurface = NULL;
// Creating Surfaces and Addresses
SDL_Surface *temp = NULL;
SDL_Surface *sprite = NULL;
// set sprite position
SDL_Rect dstSprite = {0, 0, 32, 32};
// Attempt to create SDL Window
window = SDL_CreateWindow("Atari Lunar Lander", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);
// Print an Error if the window fails to initialize
if (window == NULL) {
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// Create The Title of the Window
SDL_SetWindowTitle(window, "Atari Lunar Lander");
// Create SDL Render Window
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE;
renderer = SDL_CreateRenderer(window, -1, render_flags);
// if rendering the window fails
if (!renderer) {
printf("error creating render: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
windowSurface = SDL_GetWindowSurface(window);
// Load A bitmap image as an Surface
windowSurface = SDL_LoadBMP("/Users/jeremiahonwubuya/Desktop/AtariLunarLander/outerspace.bmp");
if (!windowSurface) {
printf("error creating surface: %s\n", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
//Load Image data into graphics hardware memory
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, windowSurface);
if (!texture) {
printf("error creating texture: %s\n", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// load bitmap image into an SDL_Surface "temp" and store "temp" into the SDL_Surface "sprite" that is optimized for Blitting
temp = SDL_LoadBMP("/Users/jeremiahonwubuya/Desktop/AtariLunarLander/player.bmp");
sprite = SDL_ConvertSurface(temp, temp->format, 0);
SDL_FreeSurface(temp);
SDL_Texture *playerTexture = SDL_CreateTextureFromSurface(renderer, sprite);
if (!sprite) {
printf("error creating sprite: %s\n", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// updating the Window Surface to be the BitMap Image
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
SDL_RenderPresent(renderer);
bool isRunning = true;
SDL_Event event;
while (isRunning) {
while (SDL_PollEvent(&event) != 0 ) {
if (event.type == SDL_QUIT) {
// close button clicked
isRunning = false;
break;
}
if (event.type == SDL_KEYDOWN) {
// close program upon buttons pressed
switch(event.key.keysym.sym){
case SDLK_q:
printf("program stopped");
isRunning = false;
break;
case SDLK_ESCAPE:
printf("programm stopped");
isRunning = false;
break;
}
// Animating the Sprite
if (event.key.keysym.sym == SDLK_a || event.key.keysym.sym == SDLK_LEFT) {
dstSprite.x -= 5;
dstSprite.w = 32;
dstSprite.h = 32;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
SDL_RenderPresent(renderer);
printf("sprite moved leftt to position %d \n", dstSprite.x);
}
if (event.key.keysym.sym == SDLK_d || event.key.keysym.sym == SDLK_RIGHT) {
dstSprite.x += 5;
dstSprite.w = 32;
dstSprite.h = 32;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
SDL_RenderPresent(renderer);
printf("sprite moved right to position %d \n", dstSprite.x);
}
if (event.key.keysym.sym == SDLK_w || event.key.keysym.sym == SDLK_UP) {
dstSprite.y -= 5;
dstSprite.w = 32;
dstSprite.h = 32;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
SDL_RenderPresent(renderer);
printf("sprite moved up to position %d \n", dstSprite.y);
}
if (event.key.keysym.sym == SDLK_s || event.key.keysym.sym == SDLK_DOWN) {
dstSprite.y += 5;
dstSprite.w = 32;
dstSprite.h = 32;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderCopy(renderer, playerTexture, NULL, &dstSprite);
SDL_RenderPresent(renderer);
printf("sprite moved down to position %d \n", dstSprite.y);
}
}
// Prevent Sprite from colliding with the edges of the screen
if ( dstSprite.x < 0 ) {
dstSprite.x = 0;
}
else if ( dstSprite.x > WINDOW_WIDTH-SPRITE_SIZE ) {
dstSprite.x = WINDOW_WIDTH-SPRITE_SIZE;
}
if ( dstSprite.y < 0 ) {
dstSprite.y = 0;
}
else if ( dstSprite.y > WINDOW_HEIGHT-SPRITE_SIZE ) {
dstSprite.y = WINDOW_HEIGHT-SPRITE_SIZE;
}
// Draw the Sprite
SDL_BlitSurface(sprite, NULL, windowSurface, &dstSprite);
SDL_UpdateWindowSurface(window);
}
}
SDL_Delay(5000);
// Clean Up
// Free SDL Surfaces
SDL_FreeSurface(sprite);
sprite = NULL;
SDL_FreeSurface(windowSurface);
windowSurface = NULL;
SDL_FreeSurface(imageSurface);
imageSurface = NULL;
// Destroy Texture and Window
texture = NULL;
SDL_DestroyTexture(texture);
playerTexture = NULL;
SDL_DestroyTexture(playerTexture);
window = NULL;
SDL_DestroyWindow(window);
SDL_Quit();
}
Your OR'ing your cases thus producing different integers than what are in .sym. You should split your ORs and let them fallthrough or use an if condition. For example:
case SDLK_a:
case SDLK_LEFT:
printf("sprite moved leftt");
break;
case SDLK_d:
case SDLK_RIGHT:
printf("sprite moved right");
break;
case SDLK_w:
case SDLK_UP:
printf("sprite moved up");
break;
case SDLK_s:
case SDLK_DOWN:
printf("sprite moved down");
break;
Or
if (event.key.keysym.sym == SDLK_a || event.key.keysym.sym == SDLK_LEFT)
// do something..
So a few things, first your code is "working", I get printed the text out when I press the correct keys but you have another error, those breaks in the ifs are making you skip the bliting section, remember that breaks break the execution flow in switch, for, and while loops, you don't need them on ifs.
Also If you press a key and then don't press anything you should be getting your screen updated. I tested with this program. Tell me if it is receiving your keys..
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
SDL_Init(SDL_INIT_VIDEO);
bool isRunning = true;
SDL_Event event;
SDL_Rect dstSprite = {0, 0, 0, 0};
while (isRunning) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
// close button clicked
isRunning = false;
break;
}
if (event.type == SDL_KEYDOWN) {
// close program upon buttons pressed
switch (event.key.keysym.sym) {
case SDLK_q:
printf("program stopped");
isRunning = false;
break;
case SDLK_ESCAPE:
printf("programm stopped");
isRunning = false;
break;
}
// Animating the Sprite
if (event.key.keysym.sym == SDLK_a ||
event.key.keysym.sym == SDLK_LEFT) {
dstSprite.x -= 5;
printf("sprite moved leftt to position %d \n", dstSprite.x);
break;
}
if (event.key.keysym.sym == SDLK_d ||
event.key.keysym.sym == SDLK_RIGHT) {
dstSprite.x += 5;
printf("sprite moved right to position %d \n", dstSprite.x);
break;
}
if (event.key.keysym.sym == SDLK_w ||
event.key.keysym.sym == SDLK_UP) {
dstSprite.y -= 5;
printf("sprite moved up to position %d \n", dstSprite.y);
break;
}
if (event.key.keysym.sym == SDLK_s ||
event.key.keysym.sym == SDLK_DOWN) {
dstSprite.y += 5;
printf("sprite moved down to position %d \n", dstSprite.y);
break;
}
}
printf("update graphics\n");
}
}
}
The screen is always black. Tell me how to display the sprites correctly.
This is my code:
#define SHAPE_SIZE 32
void aff_map(SDL_Renderer *renderer)
{
SDL_Surface *img;
SDL_Texture *Tfloor
int x = 0;
int y = 0;
int map[4][8] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
SDL_Rect SrcR;
SDL_Rect DestR;
DestR.x = 0;
DestR.y = 0;
DestR.w = SHAPE_SIZE;
DestR.h = SHAPE_SIZE;
img = IMG_Load("floor.bmp");
Tfloor = SDL_CreateTextureFromSurface(renderer, img);
while (y < 4)
{
x = 0;
while (x < 8)
{
if (map[y][x] == 0)
SDL_RenderCopy(renderer, Tfloor, NULL, &DestR);
x++;
DestR.x = DestR.x + 32;
}
DestR.x = 0;
DestR.y = DestR.y + 32;
y++;
}
SDL_RenderPresent(renderer);
}
int main()
{
SDL_Window *screen;
SDL_Event evenements;
SDL_Renderer *renderer;
screen = SDL_CreateWindow("Zappy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 8 * SHAPE_SIZE -32, 4 * SHAPE_SIZE, 0);
renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(renderer);
while (42)
{
SDL_WaitEvent(&evenements);
if (evenements.window.event == SDL_WINDOWEVENT_CLOSE ||
evenements.key.keysym.sym == SDLK_ESCAPE)
{
SDL_DestroyWindow(screen);
SDL_Quit();
break;
}
aff_map(renderer);
}
return 0;
}
The error message is explicit.
It says that the "floor.bmp" has not been converted to a surface.
It means that 'img' parameter is NULL.
Try the following :
Specify the full path to your picture in IMG_Load(), for example "/home/quentin/floor.bmp"
Check the return value of IMG_Load().
I have been trying to write a shell in C but i keep getting e segmentation fault when running ls > test.txt (before implementing pipes it worked just fine) .
Here is the code. sorry if it is too long and not formated properly.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX 1024
/* fonction separe donne en exercise*/
char **separe(char *chaine, const char *separateurs)
{
char **tab;
int i, s, m, size = 10;
tab = malloc(size * sizeof(char*));
m = 0;
i = 0;
while (chaine[i] != 0)
{
// saute un séparateur
for (s = 0; separateurs[s] != 0; s++)
if (chaine[i] == separateurs[s])
break;
if (separateurs[s] != 0)
{
chaine[i++] = 0; // met un fin de chaine à la place du séparateur et avance
continue; // les séparateurs n'ont pas été épuisés
}
if (chaine[i] != 0)
tab[m++] = chaine + i;
if (m == size)
{
// si j'atteinds la limite de la taille de mon tableau, je l'agrandis.
size += 10;
tab = realloc(tab, size * sizeof(char*));
}
// saute les caractères non séparateurs
for (; chaine[i] != 0; i++)
{
for (s = 0; separateurs[s] != 0; s++)
if (chaine[i] == separateurs[s])
break;
if (separateurs[s] != 0)
break; // trouvé un caractère séparateur, j'arrête d'avancer et je passe au mot suivant
}
}
tab[m] = NULL;
return(tab);
}
void decaler2gauche(char ** tab, int pos)
{
int i = pos;
while( tab[i+2] != NULL )
{
tab[i] = tab[i+2];
i++;
}
tab[i] = NULL;
}
char** pipetest( char **arg) {
int sizeTab = 0;
int k,j;
char **newtab;
for (k = 0; arg[k] != NULL; k++)
{
sizeTab++;
}
int i =0;
while( arg[i] != NULL )
{
if( strncmp(arg[i],"|",1) == 0 )
{
for (j=0;j < i ; j++){
newtab[i] = arg[i];
}
break;
}
i++;
}
newtab[i] = NULL;
return newtab;
}
char** pipetest2( char **arg) {
int sizeTab = 0;
int k , j;
char **newtab;
for (k = 0; arg[k] != NULL; k++)
{
sizeTab++;
}
int i =0;
while( arg[i] != NULL )
{
if( strncmp(arg[i],"|",1) == 0 )
{
for ( j= i+1 ; j < sizeTab ; j++ ) {
newtab[j] = arg[j];
}
break;
}
i++;
}
newtab[sizeTab] = NULL;
return newtab;
}
/* la fonction main*/
int main(int argc, char *argv[]) {
char cmd[MAX];
char **commande; //ici on met la commande
char *newcommande[MAX]; // ici on met la commande apres avoir verifie le contenu de commande
int i, j, k,t,a, fd, fd2, raison ; // les variables utilise
char *tmp, *new_path , *new_path1 , *new_path2;
char *ge_path, *path, **tab;
int test;
int status , status2; // la variable test pour le access
char **commande1;
char **commande2;
pid_t pid , pid2;
// récupère la valeur de $PATH
ge_path = getenv("PATH");
// crée une copie locale modifiable
// (on ne doit pas modifier la zone mémoire renvoyée par getenv)
path = malloc(strlen(ge_path) + 1);
strcpy(path, ge_path);
tab = separe(path, ":");
while (1) {
int copy = 0;
int paste = 0;
int piping = 0;
int fdout;
int fdin;
int tabfd[2];
printf("myshell > ");
fgets(cmd, MAX, stdin);
commande = separe(cmd, " \n");
/* Cette boucle verifie si la commande passe en parametre est dans le PAth ou pas*/
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path = tmp;
break;
}
}
char* fileNameIn;
char* fileNameOut;
for (j = 0; commande[j] != NULL; j++)
{
if (strcmp(commande[j], ">") == 0) //out
{
fileNameOut = commande[j + 1];
fdout = open(fileNameOut, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fdout == -1)
{
perror("open\n");
exit(1);
}
decaler2gauche(commande,j);
copy = 1;
}
if (strcmp(commande[j], "<") == 0) //in
{
fileNameIn = commande[j + 1];
printf("%s\n", fileNameIn);
fdin = open(fileNameIn, O_RDONLY);
if (fdin == -1)
{
perror("open\n");
exit(1);
}
paste = 1;
decaler2gauche(commande,j);
}
if (strcmp(commande[j], "|") == 0) // pipe {
{
piping = 1;
}
newcommande[j] = commande[j];
}
if (piping) {
commande1=pipetest(newcommande);
commande2=pipetest2(newcommande);
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande1[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path1 = tmp;
break;
}
}
for (i = 0; tab[i] != NULL; i++)
{
char tmp[MAX];
sprintf(tmp, "%s/%s", tab[i], commande2[0]);
if ((test = access(tmp, X_OK)) == 0)
{
new_path2 = tmp;
break;
}
}
pipe(tabfd);
switch (pid=fork()) {
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
close(1);
dup(tabfd[1]);
if (paste)
{
if (dup2(fdin, 0) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
if (copy)
{
if (dup2(fdout, 1) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
execv(new_path1, commande1);
perror("cmd");
exit(1);
default :
wait(&status2);
break;
}
switch (pid2=fork()) {
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
close(0);
dup(tabfd[0]);
if (paste)
{
if (dup2(fdin, 0) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
if (copy)
{
if (dup2(fdout, 1) == -1)
{
perror("dup2 fdin \n");
exit(1);
}
}
execv(new_path2, commande2);
perror("cmd");
exit(1);
default :
wait(&status);
break;
}
close(tabfd[0]);
close(tabfd[1]);
}
else {
switch (pid = fork())
{
case -1: // le cas d erreur
perror("fork");
exit(1);
case 0:// le fils
if (paste)
{
if (dup2(fdin, STDIN_FILENO) == -1)
{
perror("dup2 fdin \n");
exit(1);
};
}
if (copy)
{
if (dup2(fdout, STDOUT_FILENO) == -1)
{
perror("dup2 fdin \n");
exit(1);
};
}
execv(new_path, commande);
perror("cmd");
exit(1);
default:
wait(&status);
break ;
}
}
free(commande);
free(tmp);
}
free(tab);
//free(commande);
free(path);
free(new_path);
exit(0);
}