I am writing a game in allegro and would like to load some image files. However, whenever I call al_load_bitmap, I am getting a null pointer. I am using XCode 4.1 as my IDE. I would try compiling using g++ (in case it is a path issue) however I don't know what I need to do in order to compile it in the command line with g++ (simply g++ main.cpp does not work). Anyways, here is my code:
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
for (int i = 0; i < NUM_TILES; i++)
{
switch (static_cast<Tile>(i)) {
case GRASS:
al_set_path_filename(path, "grass.png");
tileFiles[i] = al_load_bitmap(al_path_cstr(path, '/'));
if (!tileFiles[i])
{
std::cerr<<"grass.png not initialized"<<std::endl;
}
break;
case DIRT:
al_set_path_filename(path, "dirt.png");
tileFiles[i] = al_load_bitmap(al_path_cstr(path, '/'));
if (!tileFiles[i])
{
std::cerr<<"dirt.png not initialized"<<std::endl;
}
break;
default:
std::cerr
<< "Missing case statement for datatype Tile numbered at "
<< i
<< " in Board::Board (float mw, float mh, int tst)"
<< " declared in Board.cpp."
<< std::endl;
break;
}
}
I have already run:
if(!al_init_image_addon()) {
al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return -1;
}
and I have also put:
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_native_dialog.h"
at the top of my file. Neither grass.png, nor dirt.png load and they are in the exact same directory as my main.cpp file. I get no compilation errors, but I consistently get the null pointer when I try to load my images, so when it comes time to draw them to the display, they do not show. Please help!
Neither grass.png, nor dirt.png load and they are in the exact same directory as my main.cpp file
Just a debugging tip... If you were to output the result of al_path_cstr(path, '/') to the console, it should be extremely obvious why the call is failing.
ALLEGRO_RESOURCES_PATH is the location of "bundled resources," which on OS X means the directory of the executable file. (If you were to use an app bundle, then it would be the resource folder of the bundle.) As a quick check, just copy the images into the same directory that your executable file is being built.
Most IDEs have very odd directory structures, IMO. I would ultimately set it up so that you are building into something like:
/src/main.c
/include/main.h
/obj/release
/obj/debug
/bin/game.exe
/bin/game-debug.exe
/bin/image.png
But that's just my preference. Use whatever you like, but you should read the docs again to get a clear picture of the different locations that al_get_standard_path() reveals.
Okay, I had been having the same problem, and I was absolutely positive that I was looking in the correct directory and that the resources for the program were there. I used al_path_cstr(path, '/') and allegro's working directory was as expected. Then I looked at the resource file sizes....
All my resources in my build directory were zero bytes. Copied them over myself and it solved the issue. I hope this helps some one out!
Related
I am working on Windows and I am trying to write an array into a Ubuntu device using C++ in Visual Studio 2019. Here's a sample of my code:
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs, int *iAnsSize, char *sAns)
...
...
...
char pcFolderName[256];
char pcFileName[256];
sprintf(pcFolderName, "%s\\%s",pcSavePath, pcUUTSerialNumber);
sprintf(pcFileName, "%s\\calib_rfclock.conf",pcFolderName);
// WRITE TABLE ON PC
FILE *pFileW;
pFileW = fopen(pcFileName,"wb");
fwrite(&CalibTable, sizeof(char), CalibTable.hdr.v1.u32Len, pFileW);
fclose(pFileW);
}
return 0;
However, I keep having this pop-up from Microsoft Visual C++ Debug Library that says:
Debug Assertion Failed:
Program:...
File: f:\dd\vctools\crt_bld\sefl_x86\crt\src\fwrite.c
Line: 77
Expression: (stream != NULL)
...
I found this thread and I tried logging in as root on my Ubuntu device. I also tried:
mount -o remount,rw /path/to/parent/directory
chmod 777 /path/to/parent/directory
And I can also create/edit manualy any file in the directory I'm trying to write into with my code, but I get the same error when running it.
Anyone knows what could cause this? I think it could be on the Windows side, but I don't know what I am doing wrong. Thanks a lot in advance.
You never check that opening the file succeeds - and it most likely fails, which is why you get the debug pop-up. Your use of \ as directory delimiters may be the only reason why it fails, but you should check to be sure.
I suggest that you use std::filesystem::path (C++17) to build your paths. That makes it easy to create paths in a portable way. You could also make use of a C++ standard std::ofstream to create the file. That way you don't need to close it afterwards. It closes automatically when it goes out of scope.
Example:
#include <cerrno>
#include <cstring>
#include <filesystem>
#include <fstream>
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs,
int *iAnsSize, char *sAns)
{
...
// Build std::filesystem::paths:
auto pcFolderName = std::filesystem::path(pcSavePath) / pcUUTSerialNumber;
auto pcFileName = pcFolderName / "calib_rfclock.conf";
// only try to write to the file if opening the file succeeds:
if(std::ofstream pFileW(pcFileName, std::ios::binary); pFileW) {
// Successfully opened the file, now write to it:
pFileW.write(reinterpret_cast<const char*>(&CalibTable),
CalibTable.hdr.v1.u32Len);
} else {
// Opening the file failed, print the reason:
std::cerr << pcFileName << ": " << std::strerror(errno) << std::endl;
}
...
}
I am trying to change the desktop background/wallpaper to a different image with a .png file. Although when I run the program, the background turns to solid black instead.
I am certain that I typed the file name, "ksa.png", correctly in my code to be the image I want to be on my background. I used an if condition to write out the last error on a file when the error occurred and used an else condition to write out "Success" if no errors occurred; but when I run the program, it writes "Success" to the file. I have thought about using a .jpg file instead, thinking that maybe .png files just don't work. I'll give an update when I tried using that.
#include <windows.h>
#include <fstream>
int main () {
const wchar_t *filenm = L"ksa.png";
std::ofstream log;
if (SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)filenm, SPIF_UPDATEINIFILE) == FALSE) {
log.open("log.txt");
log << "Error: " << GetLastError();
log.close();
}
else {
log.open("log.txt");
log << "Success";
log.close();
}
return 0;
}
When I run this program, the desktop background is suppose to be set as the image "ksa.png". Instead it's solid black. Any help is appreciated for making this work, thank you.
UPDATE
Okay so I updated the code to where it would run a .jpg file and I'm still getting the same result. Also I moved the line log.open("log.txt") command before the SystemParametersInfo() function like Remy Lebeau suggested and it still writes out "Success" to the file. I'm still having the same problem.
Here is my updated code:
#include <windows.h>
#include <fstream>
int main () {
const wchar_t *filenm = L"3.jpg";
std::ofstream log;
log.open("log.txt");
if (SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)filenm, SPIF_UPDATEINIFILE) == FALSE) {
log << "Error: " << GetLastError();
log.close();
}
else {
log.open("log.txt");
log << "Success";
log.close();
}
return 0;
}
Emmmm,there is a problem with your picture path. I've tried your code. You can't get pictures under relative paths unless you use absolute paths.
Like Cody Gray♦'s judgment .
const wchar_t *filenm = L"C:\\Users\\strives\\Desktop\\timg.bmp";
I am trying to run this simple example in GDCM. I have installed the library c++ version and the installation works perfectly fine but I am not able to figure out how to compile and run a example.
#include "gdcmReader.h"
#include "gdcmWriter.h"
#include "gdcmAttribute.h"
#include <iostream>
int main(int argc, char *argv[])
{
if( argc < 3 )
{
std::cerr << argv[0] << " input.dcm output.dcm" << std::endl;
return 1;
}
const char *filename = argv[1];
const char *outfilename = argv[2];
// Instanciate the reader:
gdcm::Reader reader;
reader.SetFileName( filename );
if( !reader.Read() )
{
std::cerr << "Could not read: " << filename << std::endl;
return 1;
}
// If we reach here, we know for sure only 1 thing:
// It is a valid DICOM file (potentially an old ACR-NEMA 1.0/2.0 file)
// (Maybe, it's NOT a Dicom image -could be a DICOMDIR, a RTSTRUCT, etc-)
// The output of gdcm::Reader is a gdcm::File
gdcm::File &file = reader.GetFile();
// the dataset is the the set of element we are interested in:
gdcm::DataSet &ds = file.GetDataSet();
// Contruct a static(*) type for Image Comments :
gdcm::Attribute<0x0020,0x4000> imagecomments;
imagecomments.SetValue( "Hello, World !" );
// Now replace the Image Comments from the dataset with our:
ds.Replace( imagecomments.GetAsDataElement() );
// Write the modified DataSet back to disk
gdcm::Writer writer;
writer.CheckFileMetaInformationOff(); // Do not attempt to reconstruct the file meta to preserve the file
// as close to the original as possible.
writer.SetFileName( outfilename );
writer.SetFile( file );
if( !writer.Write() )
{
std::cerr << "Could not write: " << outfilename << std::endl;
return 1;
}
return 0;
}
/*
* (*) static type, means that extra DICOM information VR & VM are computed at compilation time.
* The compiler is deducing those values from the template arguments of the class.
*/
It has a few header files that it is looking for namely gdcmreader, gdcmwriter and I want to figure out the compiler flags to use to be able to run this file.
I am doing g++ a.cpp -lgdcmCommon -lgdcmDICT but that gives me the error
a.cpp:18:24: fatal error: gdcmReader.h: No such file or directory
compilation terminated.
Can you please help me out? I have searched everywhere but I can't seem to figure out how to run this file.
When using files that are in different locations of your "normal" files you must instruct the compiler and the linker how to find them.
Your code has a #include <someFile.h> command.
The <> usage means "in other path". The compiler already knows common "other paths" as for "stdio" for common libraries.
In case of "not normal", you can tell g++ where to find the headers by adding -Imydir to the command line (replace 'mydir' with the proper path)
For the libraries, static (.a) or dynamic (.so) the same history stands.
The -Lmydir tells g++ where to look for libraries.
Your command line may look like
g++ a.cpp -I/usr/include -L/usr/local/lib -lgdcmCommon -lgdcmDICT
You did not tell how did you install gdcm library, I assume that using apt system. There are two types of libraries, "normal" and "developer" ones. To be able to compile your own software, you need the latter. So, for example in Ubuntu 16.04, type apt-get install libgdcm2-dev. Then all necessary headers will be installed in /usr/include/gdcm-2.6.
I want to have my DLL's in a subdirectory of the directory where my executable is. My current directory looks like:
Main Folder: [Folder]
Program.exe
sfml.dll
Assets [Folder]
Picture.png
Music.wav
When I really want it to look like:
Main Folder: [Folder]
Program.exe
Assets [Folder]
Picture.png
Music.wav
MyDlls[Folder]
sfml.dll
When I try to put them (DLL's) in a folder I get the error message:
The program can't start because sfml-system-d-2.dll is missing from your computer. Try reinstalling the program to fix this problem.
So, then I looked into explicit linking, and followed the tutorial here:
http://www.dreamincode.net/forums/topic/118076-dlls-explicit-linking/
If explicit linking is not what I need to use, then please tell me what I need to do. Else, please tell me what is wrong with my code below: (Also, I do not know if this is static or dynamic linking..??)
// Startup.h
#ifndef STARTUP_H
#define STARTUP_H
#include <iostream>
#include <windows.h>
class Startup
{
private:
HINSTANCE hDLL;
public:
// Explicitly link SFML DLL's
typedef int(*funcAdd) (int, int);
typedef int(*funcSubtract) (int, int);
void LoadDLLs()
{
// Retrieve DLL handle.
vector<LPCSTR> libraries = {"openal32.dll",
"sfml-audio-2.dll",
"sfml-audio-d-2.dll",
"sfml-graphics-2.dll",
"sfml-graphics-d-2.dll",
"sfml-system-2.dll",
"sfml-system-d-2.dll",
"sfml-window-2.dll",
"sfml-window-d-2.dll"};
for (int i = 0; i < libraries.size(); i++)
{
hDLL = LoadLibrary(libraries[i]);
if (hDLL == NULL)
{
std::cout << "Failed to load library.\n";
}
else
{
funcAdd Add = (funcAdd)GetProcAddress(hDLL, "Add");
funcSubtract Subtract = (funcSubtract)GetProcAddress(hDLL, "Subtract");
if (Add)
std::cout << "10+10=" << Add(10, 10) << std::endl;
if (Subtract)
std::cout << "50-10=" << Subtract(50, 10) << std::endl;
FreeLibrary(hDLL);
}
std::cin.get();
}
};
#endif
You could register an App Path (see link), making sure you add your Applications alternate DLL folder location to the App Path PATH value.
You cannot do what you want directly. The code you attached will work only for dynamic loading dlls, but it is not the case.
What you want to do will be platform specific and you need to set the path for the library before executing the program.
Im using the latest SDL 2.0 version on Xubuntu 64-bits. I installed through the provided install script on the source code.
Compiling works well, however when trying to open a font or image (regardless of its extension), it will always fail to open.
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
int main (int argc, char *argvp[])
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
cout << SDL_GetError() << endl;
}
if (TTF_Init() == -1)
{
std::cout << TTF_GetError() << std::endl;
return 2;
}
TTF_Font *font1 = NULL;
font1 = TTF_OpenFont("SourceSansPro-Regular.ttf", 20);
if (font1 == NULL)
{
std::cout << "ERROR OPENING FONT = " << TTF_GetError() << std::endl;
}
TTF_CloseFont(font1);
SDL_Quit();
return 0;
}
I compiled with
g++ -Wall fontTEST.cpp -o TEST -lSDL2 -lSDL_ttf (NOTE that SDL_ttf installs as such, not as SDL2_ttf)
And get the following error: Failed to load font: 0 Couldn't load font file
This happens with images as well. I've already tried with different fonts and images, apparently it works if I compile with SDL 1.2, just not with 2.0.
Also why does the provided install script installs the lib and include folders in /user/local/?
I moved them to /usr/ but the problem persists.
Remember the following:
On Unix, file paths are case-sensitive
As said in Xonar's comment, tilde '~' expansion is a shell feature, it does not work in C/C++ programs, you should use the real path instead.
The strace log says clearly that something is wrong with the path.
You should try the following:
Rename your font file to "font.ttf"
put it in /home/user/font.ttf
use "/home/user/font.ttf" as the path in your code.