Позвольте мне начать с рекомендации - если вам вообще интересен ответ, пожалуйста, не усложняйте ответ на ваш вопрос, чем он должен быть. Подумайте, как это выглядит для других - некоторый объем кода, с проблемой, по-видимому, в том, чтобы ничего не рисовать; почему в этом примере должно быть 6 файлов? Почему это зависит от внешнего файла, которого у нас нет и, следовательно, у нас буквально нет способа проверить? Конечно, можно уменьшить его до 30 строк одного файла с помощью только инициализации и рендеринга - буквально подойдет любой «привет мир» для SDL2. И когда он работает, а ваш код - нет, вы начинаете проверять, что отличается.
Теперь к вашему вопросу. Вы не можете извлечь что-либо из вашего основного l oop, потому что ваши window
и renderer
здесь равны NULL - он был инициализирован как NULL и никогда не был установлен в другое значение. Похоже, у вас неправильное представление о том, как работают аргументы функции - в C аргументы функции передаются по значению, и любая модификация этого значения выполняется в локальной копии функции. Когда вы передаете int, функция получает копию этого int и не возвращает sh никаких изменений обратно. Если вы передаете SDL_Window*
, то вы передаете значение этого указателя (в вашем случае, NULL
); когда вы делаете SDL_CreateWindow
, вы присваиваете его локальной переменной, и однажды angain не может вернуть его вызывающей стороне, где она остается NULL. Таким образом, все ваши вызовы рендеринга передают NULL как средство рендеринга, которое, естественно, не является действительным средством рендеринга.
То же самое появляется в вашем close
- вы пытаетесь сбросить переданные копии в NULL, но это делает нет смысла, так как вы не можете изменить внешнее значение, только локально-функциональное копирование.
Классы программирования часто учат, что есть «передача по значению» и «передача по ссылке», что, я полагаю, является источником это замешательство. Я бы скорее сказал, что в C нет передачи по ссылке, вы всегда передаете значение, но указатель также является значением. Чтобы иметь возможность изменять данные, мы передаем указатель на эти данные; чтобы преобразовать int, вы можете передать int*
, но чтобы изменить SDL_Window*
, вам нужно получить указатель на указатель - SDL_Window**
. Посмотрите, как это делает сам SDL: https://wiki.libsdl.org/SDL_CreateWindowAndRenderer.
Итак, вкратце - сделайте ваш init
равным int init(SDL_Window **window, SDL_Renderer** renderer, int width, int height);
(вам не нужно const int
здесь также, поскольку это копии ширины и высоты), и соответственно измените его код. И проверьте значения window
и renderer
после этого вызова (отладчик, отладка printf, if(window==NULL)
все идет). init
может быть что-то вроде
int init(SDL_Window **owindow, SDL_Renderer **orenderer,
int width, int height)
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
//Initialization flag
int success = 1;
//Initialize SDL
if( SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
success = 0;
}
else
{
//Create window
window = SDL_CreateWindow( "Chip-8 Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN );
if( window == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = 0;
}
else
{
renderer = SDL_CreateRenderer(window, -1, 0);
if(renderer == NULL)
{
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
success = 0;
}
else
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
}
}
}
*owindow = window;
*orenderer = renderer;
return success;
}
Конечно, вызов init
должен быть изменен на init(&window, &renderer, SCREEN_WIDTH, SCREEN_HEIGHT)
.
Пока мы на этом, еще две вещи:
Заголовочные файлы должны иметь включать ограждения , иначе это может вызвать проблемы, если вы когда-либо включите его (прямо или косвенно) несколько раз.
никогда, никогда не вызывайте вашу функцию close
. В системах linux / UNIX он (без каких-либо проблем) рухнет. Подумайте о другом имени, которое не зарезервировано широко распространенными операционными системами.