SDL with C - Blocks remains after being played - c

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

Related

Vpx temporal svc decoder

I would like to test libvpx (vp9) temporal svc. For that matter I take examples/vpx_temporal_svc_encoder.c and modify it to add a decoder. If I take for example mode 3 with 3 temporal layers and 6 frame period and try to decode only layer 0 or layers 0 and 1 I get an error: "Failed to decode frame.: Corrupt frame detected. Failed to decode tile data". What am I missing ? Here is my code (had to remove unmodified part due to post limits):
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This is an example demonstrating how to implement a multi-layer VPx
// encoding scheme based on temporal scalability for video applications
// that benefit from a scalable bitstream.
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./vpx_config.h"
#include "./y4minput.h"
#include "../vpx_ports/vpx_timer.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "vpx_ports/bitops.h"
#include "../tools_common.h"
#include "../video_writer.h"
#include "vpx/vpx_decoder.h"
#define ROI_MAP 0
#define zero(Dest) memset(&(Dest), 0, sizeof(Dest));
static const char *exec_name;
void usage_exit(void) { exit(EXIT_FAILURE); }
// Denoiser states for vp8, for temporal denoising.
enum denoiserStateVp8 {
kVp8DenoiserOff,
kVp8DenoiserOnYOnly,
kVp8DenoiserOnYUV,
kVp8DenoiserOnYUVAggressive,
kVp8DenoiserOnAdaptive
};
// Denoiser states for vp9, for temporal denoising.
enum denoiserStateVp9 {
kVp9DenoiserOff,
kVp9DenoiserOnYOnly,
// For SVC: denoise the top two spatial layers.
kVp9DenoiserOnYTwoSpatialLayers
};
static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
int main(int argc, char **argv) {
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
vpx_codec_ctx_t codec;
vpx_codec_enc_cfg_t cfg;
int frame_cnt = 0;
vpx_image_t raw;
vpx_codec_err_t res;
unsigned int width;
unsigned int height;
uint32_t error_resilient = 0;
int speed;
int frame_avail;
int got_data;
int flags = 0;
unsigned int i;
int pts = 0; // PTS starts at 0.
int frame_duration = 1; // 1 timebase tick per frame.
int layering_mode = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
int flag_periodicity = 1;
#if ROI_MAP
vpx_roi_map_t roi;
#endif
vpx_svc_layer_id_t layer_id;
const VpxInterface *encoder = NULL;
struct VpxInputContext input_ctx;
struct RateControlMetrics rc;
int64_t cx_time = 0;
const int min_args_base = 13;
#if CONFIG_VP9_HIGHBITDEPTH
vpx_bit_depth_t bit_depth = VPX_BITS_8;
int input_bit_depth = 8;
const int min_args = min_args_base + 1;
#else
const int min_args = min_args_base;
#endif // CONFIG_VP9_HIGHBITDEPTH
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
zero(rc.layer_target_bitrate);
memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
memset(&input_ctx, 0, sizeof(input_ctx));
/* Setup default input stream settings */
input_ctx.framerate.numerator = 30;
input_ctx.framerate.denominator = 1;
input_ctx.only_i420 = 1;
input_ctx.bit_depth = 0;
exec_name = argv[0];
// Check usage and arguments.
if (argc < min_args) {
#if CONFIG_VP9_HIGHBITDEPTH
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
"<error_resilient> <threads> <mode> "
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
argv[0]);
#else
//./vpx_temporal_svc_encoder ../9.yuv svc vp9 256 256 1 25 9 0 0 1 3 500000 500000 50000
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
"<error_resilient> <threads> <mode> "
"<Rate_0> ... <Rate_nlayers-1> \n",
argv[0]);
#endif // CONFIG_VP9_HIGHBITDEPTH
}
encoder = get_vpx_encoder_by_name(argv[3]);
if (!encoder) die("Unsupported codec.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
width = (unsigned int)strtoul(argv[4], NULL, 0);
height = (unsigned int)strtoul(argv[5], NULL, 0);
if (width < 16 || width % 2 || height < 16 || height % 2) {
die("Invalid resolution: %d x %d", width, height);
}
layering_mode = (int)strtol(argv[12], NULL, 0);
if (layering_mode < 0 || layering_mode > 13) {
die("Invalid layering mode (0..12) %s", argv[12]);
}
if (argc != min_args + mode_to_num_layers[layering_mode]) {
die("Invalid number of arguments");
}
input_ctx.filename = argv[1];
open_input_file(&input_ctx);
#if CONFIG_VP9_HIGHBITDEPTH
switch (strtol(argv[argc - 1], NULL, 0)) {
case 8:
bit_depth = VPX_BITS_8;
input_bit_depth = 8;
break;
case 10:
bit_depth = VPX_BITS_10;
input_bit_depth = 10;
break;
case 12:
bit_depth = VPX_BITS_12;
input_bit_depth = 12;
break;
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
}
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(
&raw,
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#else
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Populate encoder configuration.
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
return EXIT_FAILURE;
}
// Update the default configuration with our settings.
cfg.g_w = width;
cfg.g_h = height;
#if CONFIG_VP9_HIGHBITDEPTH
if (bit_depth != VPX_BITS_8) {
cfg.g_bit_depth = bit_depth;
cfg.g_input_bit_depth = input_bit_depth;
cfg.g_profile = 2;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0);
cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0);
speed = (int)strtol(argv[8], NULL, 0);
if (speed < 0) {
die("Invalid speed setting: must be positive");
}
if (strncmp(encoder->name, "vp9", 3) == 0 && speed > 9) {
warn("Mapping speed %d to speed 9.\n", speed);
}
for (i = min_args_base;
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
if (strncmp(encoder->name, "vp8", 3) == 0)
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
else if (strncmp(encoder->name, "vp9", 3) == 0)
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
}
// Real time parameters.
cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0);
cfg.rc_end_usage = VPX_CBR;
cfg.rc_min_quantizer = 2;
cfg.rc_max_quantizer = 56;
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
cfg.rc_undershoot_pct = 50;
cfg.rc_overshoot_pct = 50;
cfg.rc_buf_initial_sz = 600;
cfg.rc_buf_optimal_sz = 600;
cfg.rc_buf_sz = 1000;
// Disable dynamic resizing by default.
cfg.rc_resize_allowed = 0;
// Use 1 thread as default.
cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
if (error_resilient != 0 && error_resilient != 1) {
die("Invalid value for error resilient (0, 1): %d.", error_resilient);
}
// Enable error resilient mode.
cfg.g_error_resilient = error_resilient;
cfg.g_lag_in_frames = 0;
cfg.kf_mode = VPX_KF_AUTO;
// Disable automatic keyframe placement.
cfg.kf_min_dist = cfg.kf_max_dist = 3000;
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
&flag_periodicity);
set_rate_control_metrics(&rc, &cfg);
if (input_ctx.file_type == FILE_TYPE_Y4M) {
if (input_ctx.width != cfg.g_w || input_ctx.height != cfg.g_h) {
die("Incorrect width or height: %d x %d", cfg.g_w, cfg.g_h);
}
if (input_ctx.framerate.numerator != cfg.g_timebase.den ||
input_ctx.framerate.denominator != cfg.g_timebase.num) {
die("Incorrect framerate: numerator %d denominator %d",
cfg.g_timebase.num, cfg.g_timebase.den);
}
}
framerate = cfg.g_timebase.den / cfg.g_timebase.num;
// Open an output file for each stream.
for (i = 0; i < cfg.ts_number_layers; ++i) {
char file_name[PATH_MAX];
VpxVideoInfo info;
info.codec_fourcc = encoder->fourcc;
info.frame_width = cfg.g_w;
info.frame_height = cfg.g_h;
info.time_base.numerator = cfg.g_timebase.num;
info.time_base.denominator = cfg.g_timebase.den;
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[i]) die("Failed to open %s for writing", file_name);
assert(outfile[i] != NULL);
}
// No spatial layers in this encoder.
cfg.ss_number_layers = 1;
// Initialize codec.
#if CONFIG_VP9_HIGHBITDEPTH
if (vpx_codec_enc_init(
&codec, encoder->codec_interface(), &cfg,
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
#else
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
#endif // CONFIG_VP9_HIGHBITDEPTH
die("Failed to initialize encoder");
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
#endif
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_svc_extra_cfg_t svc_params;
memset(&svc_params, 0, sizeof(svc_params));
vpx_codec_control(&codec, VP9E_SET_POSTENCODE_DROP, 0);
vpx_codec_control(&codec, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0);
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads));
vpx_codec_control(&codec, VP9E_SET_DISABLE_LOOPFILTER, 0);
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 0);
#endif
if (cfg.g_threads > 1)
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
else
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
die_codec(&codec, "Failed to set SVC");
for (i = 0; i < cfg.ts_number_layers; ++i) {
svc_params.max_quantizers[i] = cfg.rc_max_quantizer;
svc_params.min_quantizers[i] = cfg.rc_min_quantizer;
}
svc_params.scaling_factor_num[0] = cfg.g_h;
svc_params.scaling_factor_den[0] = cfg.g_h;
vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params);
}
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
}
vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1);
// This controls the maximum target size of the key frame.
// For generating smaller key frames, use a smaller max_intra_size_pct
// value, like 100 or 200.
{
const int max_intra_size_pct = 1000;
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
max_intra_size_pct);
}
const VpxInterface *decoder = NULL;
decoder = get_vpx_decoder_by_name( "vp9" );
if (!decoder) die("Unsupported codec.");
vpx_codec_ctx_t codec_dec;
vpx_codec_dec_cfg_t cfg_dec;
cfg_dec.w = width;
cfg_dec.h = height;
cfg_dec.threads = 1;
if (vpx_codec_dec_init( &codec_dec, decoder->codec_interface(), &cfg_dec, 0))
die_codec( &codec_dec, "Failed to initialize decoder.");
if(!codec.iface)
die_codec( &codec_dec, "vvv no iface" );
vpx_image_t *img_dec;
frame_avail = 1;
while (frame_avail || got_data) {
struct vpx_usec_timer timer;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt;
// Update the temporal layer_id. No spatial layers in this test.
layer_id.spatial_layer_id = 0;
layer_id.temporal_layer_id =
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id;
if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
} else if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_TEMPORAL_LAYER_ID,
layer_id.temporal_layer_id);
}
flags = layer_flags[frame_cnt % flag_periodicity];
if (layering_mode == 0) flags = 0;
frame_avail = read_frame(&input_ctx, &raw);
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
VPX_DL_REALTIME)) {
die_codec(&codec, "Failed to encode frame");
}
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
// Reset KF flag.
if (layering_mode != 7) {
layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
}
got_data = 0;
while ((pkt = vpx_codec_get_cx_data(&codec, &iter))) {
got_data = 1;
switch (pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT:
for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
i < cfg.ts_number_layers; ++i) {
vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf,
pkt->data.frame.sz, pts);
++rc.layer_tot_enc_frames[i];
rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz;
// Keep count of rate control stats per layer (for non-key frames).
if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] &&
!(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz;
rc.layer_avg_rate_mismatch[i] +=
fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) /
rc.layer_pfb[i];
++rc.layer_enc_frames[i];
}
}
// Update for short-time encoding bitrate states, for moving window
// of size rc->window, shifted by rc->window / 2.
// Ignore first window segment, due to key frame.
if (rc.window_size == 0) rc.window_size = 15;
if (frame_cnt > rc.window_size) {
sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate / rc.window_size) *
(sum_bitrate / rc.window_size);
sum_bitrate = 0.0;
}
}
// Second shifted window.
if (frame_cnt > rc.window_size + rc.window_size / 2) {
sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt > 2 * rc.window_size &&
frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate2 / rc.window_size) *
(sum_bitrate2 / rc.window_size);
sum_bitrate2 = 0.0;
}
}
//decode
if( layer_id.temporal_layer_id == 0 ){
vpx_codec_control(&codec_dec, VP9E_SET_SVC_LAYER_ID, &layer_id);
vpx_codec_err_t res = vpx_codec_decode(&codec_dec, pkt->data.frame.buf, pkt->data.frame.sz, NULL, 0);
if( res )
die_codec(&codec_dec, "Failed to decode frame.");
vpx_codec_iter_t iter = NULL;
img_dec = vpx_codec_get_frame(&codec_dec, &iter);
if( img_dec == NULL )
die_codec(&codec_dec, "No frames were decoded.");
if( vpx_codec_get_frame(&codec_dec, &iter) != NULL )
die_codec(&codec_dec, "More than on frame decoded.");
printf( "decoded frame\n" );
}
break;
default: break;
}
}
++frame_cnt;
pts += frame_duration;
}
close_input_file(&input_ctx);
printout_rate_control_summary(&rc, &cfg, frame_cnt);
printf("\n");
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1000000 * (double)frame_cnt / (double)cx_time);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
// Try to rewrite the output file headers with the actual frame count.
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
if (input_ctx.file_type != FILE_TYPE_Y4M) {
vpx_img_free(&raw);
}
#if ROI_MAP
free(roi.roi_map);
#endif
return EXIT_SUCCESS;
}

My program has AddressSanitizer error but I'm not sure how to read it

I'm relatively new to C and just finished a train station schedule program that looks for the nearest time departing time, from a schedule file, relative to the user input time, source, and destination. The restrictions were no string.h and no dynamic memory allocation of any kind. The program worked fine when I tested it but when marked, it produced AddressSanitizer errors which we haven't learned yet. I'm not sure how to read the error code.
The Following is my code:
#include <stdio.h>
#include <stdlib.h>
#define lineSize 4096
int main(int argc, char* argv[]) {
if(argc != 4){
printf("Please provide <source> <destination> <time> as command line arguments\n");
return(0);
}
int c = 0;
while(argv[3][c] != 0){
c++;
}
if(c < 8){
printf("Please enter a proper time\n");
return(0);
}
char line[lineSize];
FILE * fpointer = fopen("timetable.list", "r");
int i;
int j;
int StartSize;
int DestinationSize;
int DepartTime;
for(StartSize = 0; argv[1][StartSize] != '\0'; StartSize += 1){
continue;
}
for(DestinationSize = 0; argv[2][DestinationSize] != '\0'; DestinationSize += 1){
continue;
}
for(DepartTime = 0; argv[3][DepartTime] != '\0'; DepartTime += 1){
continue;
}
int hour = 23;
int min = 59;
int sec = 59;
int check = 1;
int matchStart = 0;
int matchEnd = 0;
int checkNearestTime = 0;
int isThereATime = 0;
while(fgets(line, lineSize, fpointer) != NULL){
check = 1;
for(i = 0; i < StartSize; i++){
if(argv[1][i] == line[i]){
matchStart = 1;
continue;
}
else{
check = 0;
matchStart = 0;
}
}
if(check == 1){
i = 0;
int j = StartSize + 2;
while(i < DestinationSize){
if(argv[2][i] == line[j]){
i += 1;
j += 1;
matchEnd = 1;
}
else{
check = 0;
matchEnd = 0;
break;
}
}
}
if(check == 1){
i = 0;
j = StartSize + DestinationSize + 4;
while(i < DepartTime){
if(argv[3][i] == line[j]){
i += 1;
j += 1;
}
else{
check = 0;
break;
}
}
if(check == 1){
printf("The next train to %s from %s departs at %s\n", argv[2], argv[1], argv[3]);
return 0;
}
if(check == 0){
j = StartSize + DestinationSize + 4;
int lineFullHour = (line[j] - '0') * 10 + (line[j+1] -'0');
int lineFullMin = (line[j+3] - '0') * 10 + (line[j+4] -'0');
int lineFullSec = (line[j+6] - '0') * 10 + (line[j+7] -'0');
int argvHour = (argv[3][0] - '0') * 10 + (argv[3][1]-'0');
int argvMin = (argv[3][3] - '0') * 10 + (argv[3][4] -'0');
int argvSec = (argv[3][6] - '0') * 10 + (argv[3][7] -'0');
if(lineFullHour > argvHour){
if(lineFullHour < hour){
hour = lineFullHour;
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullHour == hour){
if(lineFullMin < min){
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullMin == min){
if(lineFullSec < sec){
sec = lineFullSec;
checkNearestTime = 1;
}
}
}
}
else if(lineFullHour == argvHour && lineFullMin > argvMin){
if(lineFullHour < hour){
hour = lineFullHour;
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullHour == hour){
if(lineFullMin < min){
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullMin == min){
if(lineFullSec < sec){
sec = lineFullSec;
checkNearestTime = 1;
}
}
}
}
else if(lineFullHour == argvHour && lineFullMin == argvMin && lineFullSec > argvSec){
if(lineFullHour < hour){
hour = lineFullHour;
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullHour == hour){
if(lineFullMin < min){
min = lineFullMin;
sec = lineFullSec;
checkNearestTime = 1;
}
else if(lineFullMin == min){
if(lineFullSec < sec){
sec = lineFullSec;
checkNearestTime = 1;
}
}
}
}
}
}
if(matchStart == 1 && matchEnd == 1 && checkNearestTime == 1){
isThereATime = 1;
}
}
if(isThereATime == 1){
printf("The next train to %s from %s departs at %02d:%02d:%02d\n", argv[2], argv[1], hour, min, sec);
return 0;
}
if(isThereATime == 0){
printf("No suitable trains can be found\n");
return 0;
}
return 0;
}
The source code (line 53) and your report do not match (line 59) do not match. It complains about a NULL pointer, per #kaylum, that only happens if fpointer is NULL. In turn this means │FILE * fpointer = fopen("timetable.list", "r"); failed. Always implement error checking:
#include <errno.h>
#include <string.h>
...
FILE * fpointer = fopen("timetable.list", "r");
if(!fpointer) {
fprintf(stderr, "fopen failed with %s", strerror(errno)));
exit(1);
}

find the line which causes the segmentation fault, which I couldn't find

Currently I am writing a LZ77 algorithm. When I try to run my code, for some reason I get the ZSH segmentation fault. I've searched some topics but I couldn't find where to fix my code for this.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*#define pencereBoyutu 60
#define bufferBoyutu 40*/
typedef enum { false, true } bool;
// ============================================================================
int ortakBul(unsigned char window[], unsigned char str[], int strLen) {
int j, k, yer = -1;
int pencereBoyutu = 60;
for (int i = 0; i <= pencereBoyutu - strLen; i++) {
yer = k = i;
for (j = 0; j < strLen; j++) {
if (str[j] == window[k])
k++;
else
break;
}
if (j == strLen)
return yer;
}
return -1;
}
// ============================================================================
int compress(char* inputPath) {
FILE *fileInput;
FILE *fileOutput;
bool last = false;
int girisUzunlugu = 0;
int cikisUzunlugu = 0;
int setSonu = 0;
int yer = -1;
int i, size, shift, c_in;
size_t bytesRead = (size_t) -1;
int arrayBoyutu = 100;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
unsigned char c;
unsigned char array[arrayBoyutu];
unsigned char window[pencereBoyutu];
unsigned char buffer[bufferBoyutu];
unsigned char bufferYukle[bufferBoyutu];
unsigned char str[bufferBoyutu];
// input out açmak
char path[30] = "";
strcat(path, inputPath);
fileInput = fopen(path, "rb");
fileOutput = fopen("output/output.lz77", "wb");
// mümkün değilse error ver
if (!fileInput) {
fprintf(stderr, "fileInput acilamiyor. %s", inputPath);
return 0;
}
// fileinput uzunluğunu çek
fseek(fileInput, 0, SEEK_END);
girisUzunlugu = ftell(fileInput);
fseek(fileInput, 0, SEEK_SET);
fprintf(stdout, "Giris dosyasi boyutu: %d byte", girisUzunlugu);
// dosya boşsa hata ver
if (girisUzunlugu == 0)
return 3;
// eğer dosya boyutu arrayboyutundan düşükse hata ver
if (girisUzunlugu < arrayBoyutu)
return 2;
// arrayı byte olarak oku
fread(array, 1, arrayBoyutu, fileInput);
fwrite(array, 1, pencereBoyutu, fileOutput);
// LZ77 mantığı
while (true) {
if ((c_in = fgetc(fileInput)) == EOF)
last = true;
else
c = (unsigned char) c_in;
for (int k = 0; k < pencereBoyutu; k++)
window[k] = array[k];
for (int k = pencereBoyutu, j = 0; k < arrayBoyutu; k++, j++) {
buffer[j] = array[k];
str[j] = array[k];
}
// en uzun ortak kelimeyi bulmak
if (setSonu != 0) {
size = bufferBoyutu - setSonu;
if (setSonu == bufferBoyutu)
break;
}
else {
size = bufferBoyutu;
}
yer = -1;
for (i = size; i > 0; i--) {
yer = ortakBul(window, str, i);
if (yer != -1)
break;
}
// hiç ortak bulunmaması halinde
if (yer == -1) {
fputc(255, fileOutput);
fputc(buffer[0], fileOutput);
shift = 1;
}
// ortak bulunması halinde
else {
fputc(pencereBoyutu - yer, fileOutput);
fputc(i, fileOutput);
if (i == bufferBoyutu) {
shift = bufferBoyutu + 1;
if (!last)
fputc(c, fileOutput);
else
setSonu = 1;
}
else {
if (i + setSonu != bufferBoyutu)
fputc(buffer[i], fileOutput);
else
break;
shift = i + 1;
}
}
// Shift buffer
for (int j = 0; j < arrayBoyutu - shift; j++)
array[j] = array[j + shift];
if (!last)
array[arrayBoyutu - shift] = c;
if (shift == 1 && last)
setSonu++;
if (shift != 1) {
// yeni bitler oku
bytesRead = fread(bufferYukle, 1, (size_t) shift - 1, fileInput);
// yeni bitleri arraya yükle
for (int k = 0, l = arrayBoyutu - shift + 1; k < shift - 1; k++, l++)
array[l] = bufferYukle[k];
if (last) {
setSonu += shift;
continue;
}
if (bytesRead < shift - 1)
setSonu = shift - 1 - bytesRead;
}
}
// fileoutput uzunluğunu çek
fseek(fileOutput, 0, SEEK_END);
cikisUzunlugu = ftell(fileOutput);
fseek(fileOutput, 0, SEEK_SET);
fprintf(stdout, "\nCikis dosya boyutu: %d byte\n", cikisUzunlugu);
// I/O dosyaları kapanması
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
// Decompress
int decompress() {
FILE *fileInput;
FILE *fileOutput;
int shift, denge, ortak, c_in;
bool done = false;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
int arrayBoyutu = pencereBoyutu + bufferBoyutu;
unsigned char c;
unsigned char window[pencereBoyutu];
unsigned char writeBuffer[pencereBoyutu];
unsigned char readBuffer[2];
// i/o dosyalarin acilmasi
fileInput = fopen("output/output.lz77", "rb");
fileOutput = fopen("output/file", "wb");
if (!fileInput) {
fprintf(stderr, "fileInput açılamıyor. %s", "output.lz77");
return 0;
}
fread(window, 1, pencereBoyutu, fileInput);
fwrite(window, 1, pencereBoyutu, fileOutput);
// decompress mantığı
while (true) {
size_t bytesRead = fread(readBuffer, 1, 2, fileInput);
if (bytesRead >= 2) {
denge = (int) readBuffer[0];
ortak = (int) readBuffer[1];
if (denge == 255) {
denge = 0;
c = (unsigned char) ortak;
ortak = 0;
shift = ortak + 1;
}
else {
shift = ortak + 1;
c_in = fgetc(fileInput);
if (c_in == EOF)
done = true;
else
c = (unsigned char) c_in;
}
for (int i = 0, j = pencereBoyutu - denge; i < ortak; i++, j++)
writeBuffer[i] = window[j];
fwrite(writeBuffer, 1, (size_t) ortak, fileOutput);
if (!done)
fputc(c, fileOutput);
// Shift window
for (int i = 0; i < pencereBoyutu - shift; i++)
window[i] = window[i + shift];
for (int i = 0, j = pencereBoyutu - shift; i < ortak; i++, j++)
window[j] = writeBuffer[i];
window[pencereBoyutu - 1] = c;
}
else {
break;
}
}
// dosyaları kapat
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
int main(int argc, char* argv[]) {
clock_t begin = clock();
if (argc < 2) {
printf("2 argüman gerekiyor: [-c|-d] [dosya_yolu]");
} else {
// decompress
if (strcmp(argv[1], "-d") == 0) {
int result = decompress();
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
}
}
// compress
else if (strcmp(argv[1], "-c") == 0) {
int result = compress(argv[2]);
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI\n");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
} else if (result == 2) {
fprintf(stderr, "\nDosya cok kucuk.\n");
} else if (result == 3) {
fprintf(stderr, "\nDosya bos.\n");
}
} else {
printf("Gecersiz argumanlar.");
}
}
// calistirma zamanını bastırmak
clock_t end = clock();
printf("\n\nCalistirma zamani: ");
printf("%f", ((double) (end - begin) / CLOCKS_PER_SEC));
printf(" [saniye]");
return 0;
}
// ============================================================================
After compiling you have to give arguments for running:
./lz77 -c input.txt
when I try to run my application with the input above which has 100 characters in it, it gives me segmentation fault. I couldn't find any reason after done some research about it. I'll be so happy if anyone can help.

How to save entered strings and integers in C

Can anyone help me on my code. What it should do is when I enter "create 6 5" its supposed to create a 6x5 rectangular shape with *'s, but will not show yet unless I entered "show".
This is the code i'm working on, it is not correct yet, still figuring out how to do it.
i'm new in programming.
char s[100];
char *s1 = "show";
char *s2 = "create";
int main()
{
int zWidth = 0, zHeight = 0, zLoop = 0, aLoop = 0;
do
{
scanf("%s %d %d", &s, &zWidth, &zHeight);
}
while (strcmp(s1, s) != 0);
if(strcmp(s2, s) == 0)
{
//To draw the first horizontal line
for(zLoop = 0; zLoop < zWidth; zLoop++)
printf("*");
printf("\n");
//Drawing the vertical lines
for(zLoop = 2; zLoop < zHeight; zLoop++)
{
printf("*");
for(zLoop = 0; aLoop < zWidth-2; aLoop++)
printf("*");
printf("*\n");
}
//Last horizontal Line
for(zLoop = 0; zLoop < zWidth; zLoop++)
printf("*");
printf("\n");
}
return 0;
}
#include <stdio.h>
enum command_state {
SHOW, CREATE, QUIT, HELP, INVALID
};
char Command_line[100];
const char *Show = "show";
const char *Create = "create";
const char *Quit = "quit";
const char *Help = "help";
const char *QMark = "?";
enum command_state command(void){
if(fgets(Command_line, sizeof(Command_line), stdin) != NULL){
char operation[16];
sscanf(Command_line, "%15s", operation);
if(!strcmp(operation, Show))
return SHOW;
else if(!strcmp(operation, Create))
return CREATE;
else if(!strcmp(operation, Quit))
return QUIT;
else if(!strcmp(operation, Help) || !strcmp(operation, QMark))
return HELP;
else
return INVALID;
}
return QUIT;//input EOF
}
int main(void){
int rWidth = 0, rHeight = 0, aLoop = 1;
while(aLoop){
switch(command()){
case SHOW :
if(rWidth == 0 || rHeight == 0)
printf("execute create is required before\n");
else {
int h, w;
for(h = 0; h < rHeight; h++) {
for(w = 0; w < rWidth; w++)
printf("*");
printf("\n");
}
}
break;
case CREATE :
if(2!=sscanf(Command_line, "create %d %d", &rWidth, &rHeight) ||
rWidth < 1 || rHeight < 1){
rWidth = rHeight = 0;
printf("invalid create command\n");
}
break;
case QUIT :
aLoop = 0;
break;
case HELP :
printf(
"help or ? : this\n"
"create w h: set to size of rectangle width and height\n"
"show : draw filled rectangle\n"
"quit : end of program\n"
);
break;
default :
printf("invalid command\n");
}
}
return 0;
}

C - segmentation fault on long running while loop

I wrote small daemon for rotating screen on Thinkpad X41 convertible laptop using built-in motion sensor (used by harddisk active protection system) or manually by button. Program works very well, but after some amount of time (5 to 15 minutes) will crash with segfault.
I know there are lot of scripts on the internet to do this written in bash or python, but none of them suit my needs and vision how should program work.
I know that for example mentioned bash is probably better for this, but I have zero experiences with it compared to C In which I have at least minimal basic experiences from few high school lessons, so I choose this.
here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define TRUE 1
#define FALSE 0
#define NIL -1
#define XRANDR_GREP_COMMAND "xrandr -q --verbose|grep LVDS1|cut -b37-37"
#define DAEMON_LOCK_FILE "/dev/shm/thinkrotate.lock"
#define DAEMON_STATE_FILE "/dev/shm/thinkrotate.st"
#define SWIVEL_STATE_FILE "/sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode"
#define GYRO_STATE_FILE "/sys/devices/platform/hdaps/position"
#define BUBBLE_TERMINATED "notify-send 'Ukončenie programu' 'ThinkRotate démon dostal príkaz na ukončenie'"
#define BUBBLE_SWIVEL_DOWN "notify-send 'Notebook v tablet móde' 'Veko bolo sklopené, aktivovaná automatická rotácia'"
#define BUBBLE_SWIVEL_UP "notify-send 'Notebook v štandartnom režime' 'Rotácia je deaktivovaná'"
#define BUBBLE_RETURN_POSITION "notify-send 'Automatická rotácia zapnutá' 'Pre vypnutie automatickej rotácie obrazu stlačte tlačítko rotácie.'"
#define BUBBLE_START_MANUAL_ROTATION "notify-send 'Automatická rotácia vypnutá' 'Rotácia bude zapnutá znovu až pri návrate do tejto polohy, dovtedy na otáčanie obrazu používajte tlačidlo.'"
#define SWIVEL_DOWN_COMMANDS ""
#define SWIVEL_UP_COMMANDS ""
#define WIDTH_COMMANDS ""
#define HEIGHT_COMMANDS ""
int get_lock(void) {
int fdlock;
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if((fdlock = open(DAEMON_LOCK_FILE, O_WRONLY|O_CREAT, 0666)) == -1) { return 0; }
if(fcntl(fdlock, F_SETLK, &fl) == -1) { return 0; }
return 1;
}
int next_rotation(int direction) {
int next;
int pos;
pos = current_pos();
if (direction == 1) {
switch (pos) {
case 0:
next = 1;
break;
case 1:
next = 2;
break;
case 2:
next = 3;
break;
case 3:
next = 0;
break;
}
} else if (direction == 2) {
switch (pos) {
case 0:
next = 3;
break;
case 1:
next = 0;
break;
case 2:
next = 1;
break;
case 3:
next = 2;
break;
}
}
return next;
}
int current_pos(void) {
FILE *frotpos;
char rotpos;
int pos;
frotpos = popen(XRANDR_GREP_COMMAND, "r");
fscanf(frotpos, "%c", &rotpos);
fclose(frotpos);
switch (rotpos) {
case 110:
pos = 0;
break;
case 108:
pos = 1;
break;
case 105:
pos = 2;
break;
case 114:
pos = 3;
break;
}
return pos;
}
void rotate(int poz) {
char buff[32];
if ((poz == 2)||(poz == 0)) {
system(WIDTH_COMMANDS);
} else {
system(HEIGHT_COMMANDS);
}
sprintf(buff, "xrandr -o %i", poz);
system(buff);
}
int main(int argc, char *argv[]) {
if(!get_lock()) {
if (argc >= 2) {
int cmd;
FILE *fparams;
fparams = fopen(DAEMON_STATE_FILE, "w");
if (!strncmp(argv[1], "r", 1)) { cmd = 1; }
else if (!strncmp(argv[1], "l", 1)) { cmd = 2; }
else if (!strncmp(argv[1], "k", 1)) { cmd = 0; }
fprintf(fparams, "%i", cmd);
fclose(fparams);
}
return 1;
}
int autorotate = TRUE;
int prevmode = NIL;
FILE *fstate;
int tabletmode;
FILE *fgyrovals;
char gyroval_x[5];
char gyroval_y[5];
int x;
int y;
FILE *fargs;
int argum = NIL;
int next_p;
int prev_p = current_pos();
int last_auto_p = NIL;
while (TRUE) {
fstate = fopen(SWIVEL_STATE_FILE, "r");
fscanf(fstate, "%d", &tabletmode);
if (fargs = fopen(DAEMON_STATE_FILE, "r")) {
if (fscanf(fargs, "%d", &argum) == NIL) { argum = NIL; }
}
fargs = fopen(DAEMON_STATE_FILE, "w");
fclose(fargs);
fclose(fstate);
if (argum == 0) {
system(BUBBLE_TERMINATED);
return 1;
}
if (prevmode != tabletmode) {
if (tabletmode) {
system(BUBBLE_SWIVEL_DOWN);
system(SWIVEL_DOWN_COMMANDS);
} else {
system(BUBBLE_SWIVEL_UP);
system(SWIVEL_UP_COMMANDS);
rotate(0);
}
}
if (tabletmode) {
if (argum == 1 || argum == 2) {
next_p = next_rotation(argum);
if (next_p == last_auto_p) {
rotate(next_p);
autorotate = TRUE;
last_auto_p = NIL;
system(BUBBLE_RETURN_POSITION);
} else if ((autorotate)&&(current_pos() == last_auto_p)) {
autorotate = FALSE;
system(BUBBLE_START_MANUAL_ROTATION);
} else {
if (autorotate) {
system(BUBBLE_START_MANUAL_ROTATION);
last_auto_p = current_pos();
} else {
rotate(next_p);
}
autorotate = FALSE;
}
}
if (autorotate) {
fgyrovals = fopen(GYRO_STATE_FILE, "r");
fscanf(fgyrovals, "(%4[^,], %4[^)]", &gyroval_x, &gyroval_y);
fclose(fgyrovals);
x = atoi(gyroval_x);
y = atoi(gyroval_y) * (-1);
if (y < 465) {
if (x < 210) {
next_p = 1;
} else if (x > 425) {
next_p = 3;
} else {
next_p = 2;
}
} else if (y > 525) {
if (x < 210) {
next_p = 1;
} else if (x > 425) {
next_p = 3;
} else {
next_p = 0;
}
} else {
if (x < 305) {
next_p = 1;
} else if (x > 345) {
next_p = 3;
}
}
if (next_p != prev_p) {
rotate(next_p);
prev_p = next_p;
}
}
} else {
if (argum == 1 || argum == 2) {
system(BUBBLE_SWIVEL_UP);
}
}
prevmode = tabletmode;
sleep(1);
}
return 0;
}
Thanks to comment of user "inspired". Now the program is running more than a hour without segfault.
if (fargs = fopen(DAEMON_STATE_FILE, "r")) {
if (fscanf(fargs, "%d", &argum) == NIL) { argum = NIL; }
fclose(fargs);
}
fargs = fopen(DAEMON_STATE_FILE, "w");
fclose(fargs);
As said, file should be closed before opened next time for writing.

Resources