UPDATE:Check my answer for details, pointer error.
I have a function, that is supposed to load a few test assets and blit them onto screen using SDL2. This function throws a segfault immediately before executing any commands, with no clear cause. Keep in mind that some of the variables in this function are globals.
Function contents:
printf("DEBUG");
int menuSelect = 0;
printf("declare");
SDL_Surface* bg = SDL_LoadBMP("menubg.bmp");
printf("bg load");
SDL_Surface* menu1 = TTF_RenderText_Solid(font,"HACKING PROGRAM",whiteclr);
printf("title blip");
SDL_BlitSurface(bg,NULL,screen,NULL);
printf("event");
SDL_Event* event;
printf("menu2");
SDL_Surface* menu2 = TTF_RenderText_Solid(font,"Hack",whiteclr);
printf("rect");
SDL_Rect menu2r = CreateRect(5,30,menu2->w,menu2->h);
printf("free");
SDL_FreeSurface(menu2);
SDL_FreeSurface(menu1);
while(SDL_WaitEvent(event))
{
switch(event->type)
{
case SDL_MOUSEBUTTONDOWN:
if(event->motion.x > menu2r.x && event->motion.x < menu2r.x+menu2r.w && event->motion.y > menu2r.y && event->motion.y < menu2r.y+menu2r.h)
{
SDL_FreeSurface(bg);
return 0;
}
break;
case SDL_MOUSEMOTION:
if(event->motion.x > menu2r.x && event->motion.x < menu2r.x+menu2r.w && event->motion.y > menu2r.y && event->motion.y < menu2r.y+menu2r.h)
{
menuSelect=1;
}
else
{
menuSelect=0;
}
break;
}
if(menuSelect==1)
{
menu2 = TTF_RenderText_Solid(font,"Hack",selectclr);
}
else
{
menu2 = TTF_RenderText_Solid(font,"Hack",selectclr);
}
}
return 0;
Double check the paths on fonts, images, etc. Are they correct in relation to the root directory of the project? They are quite sensitive. To avoid simple mistakes like these: go to point 2.
Apply some basic exception handling. For example:
SDL_Surface* bg = SDL_LoadBMP("menubg.bmp");
if(bg == NULL)
{
// This code will be run when menubg.bmp cannot be loaded.
}
It's good practice to always check the outcome of your statement to make sure it worked as planned.
Use a debugger. GDB is the most popular one; but I personally use DDD, a visual debugger that is run on GDB. It's very lightweight and has both graphical and console input.
Document your code. Even if it's a personal project and you're not going to show it to anyone. Explain what each statement does and why it's needed; you'll get a clearer sense of the code and you may find the problem itself.
Also, it's while(SDL_WaitEvent(&event)) not while(SDL_WaitEvent(event)).
This is actually a stupid error, and something that might happen to anyone who is a newbie to SDL. WaitEvent(SDL_Event*) should be fed &event, as in event should be the event, not a pointer to the event. By changing while(SDL_WaitEvent(event)) to while(SDL_WaitEvent(&event)) and changing SDL_Event* event; to SDL_Event event; this problem is fixed.
For anyone else experiencing any kind of segfault, debugging hard will do the job. The guys here at SO greatly helped me in tracing down and fixing my stupid error, and educated me as a developer.
Related
So I'm trying to make a keyboard handler for a side project that I'm making in SDL2. After searching around the web a bit for some help this is what I came up with.
bool Keys[322];
void init() override {
for (bool i : Keys) {
i = false;
}
}
void update() override {
if (CRS::event.type == SDL_KEYDOWN) {
Keys[CRS::event.key.keysym.sym] = true;
}
if (CRS::event.type == SDL_KEYUP) {
Keys[CRS::event.key.keysym.sym] = false;
}
if (Keys[SDLK_w]) {
Transform->Velocity.y = 0; //moves the player up
}
}
This code above works fine most of the time, but the problem occurs whenever I try to use any keys SDL considers a modifier (such as left shift, capslock, ctrl, alt, etc). Whenever I even touch one of those buttons I get a Access violation reading location error. Can anyone tell me why that is? And if I wanted to use shift, capslock, etc how would I go about doing that?
So i've decided to scrap my code after realizing that this probably isn't how I want to implement what I wanted and used the SDL_GetKeyboardStates function instead, which worked like a charm.
Alright so here is my code. This should be really simple but it doesn't want to work with me for some reason. Raycast sends a ray from the mouse, if it hits an object with a tag, it assigns a number to a variable. If it doesn't hit an object, then it sets the variable as -99. For some reason mine is hanging on:
A. I don't hit the objects, it outputs -99 the first time but after that it hangs on getting assigned 4.
B.I hit the objects and it will work just fine. After I click OFF the objects it hangs on the variable from the object I just hit previously.
em.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameFunctions : MonoBehaviour {
int Hitnum = -99;
void Start () {
}
void Update () {
if (Input.GetMouseButtonDown (0)) {
objectCheck ();
}
}
//end of UPDATE function
public void objectCheck () {
RaycastHit hit;
Ray ray = camera.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit, 10000.0f)) {
if (hit.collider.tag == "Box") {
Hitnum = 1;
} else if (hit.collider.tag == "Sphere") {
Hitnum = 2;
} else if (hit.collider.tag == "Pyramid") {
Hitnum = 3;
} else if (hit.collider.tag == "Trapezoid") {
Hitnum = 4;
} else {
Hitnum = -99;
}
}
Debug.Log (Hitnum);
}
//end of check
}
Thanks in advance. This is driving me nuts because it should be simple.
EDIT: posted full code this time, yes all of it. I should mention that there are no other objects with tags, it's just null space. This was supposed to be a very basic shape identifier for kids.
EDIT:EDIT: I expect it to put out -99 if you do not hit the object. Later I will probably do something with the numbers but right now I jest need to fix this.
Restarted unity, everything works fine now. Thanks. Looked through my settings to see what had changed. I earlier deleted the background that had a background tag on it. I guess unity decided that if there is not hit on raycast, it will get the object that it last hit?
I am trying to make my basic loading screen transition over to game level screen. So what i wanted to do is, once the loading screen is active (or has appeared onscreen), I want at this point to start loading my game state. What it is doing at the moment is loading everything at the start, and this does take a while.
So currently my project starts off with a main menu. Then when i press enter, its starts the loading screen. I have my manual state change using keypresses like so:
void Game::update()
{
static bool enterPreviouslyPressed = false;
static bool escapePreviousPressed = false;
const Uint8 *keys = SDL_GetKeyboardState(NULL);
if (keys[::SDL_SCANCODE_ESCAPE] && !escapePreviousPressed && typeid(*fsm->getState()) == typeid(GameState))
{
fsm->setState(menuState);
}
else if (keys[::SDL_SCANCODE_RETURN] && !enterPreviouslyPressed && typeid(*fsm->getState()) == typeid(MainMenuState))
{
fsm->setState(loadingState);
}
else if ((keys[::SDL_SCANCODE_RETURN] && !enterPreviouslyPressed) && typeid(*fsm->getState()) == typeid(LoadScreenState))
{
fsm->setState(gameState);
}
else if (keys[::SDL_SCANCODE_ESCAPE] && !escapePreviousPressed && typeid(*fsm->getState()) == typeid(MainMenuState))
{
exit(0);
}
enterPreviouslyPressed = keys[::SDL_SCANCODE_RETURN] != 0;
escapePreviousPressed = keys[::SDL_SCANCODE_ESCAPE] != 0;
fsm->update();
}
I did this to initially does this so i could change states manually to check that everything works. I was wondering if there was an easy(ish) way, like boolean flags for example or another simpler way to do this. I wasn't able find any tutorials online so wondering if someone knows the best solution as to how to do this. I did see a question on here, kindda similar but I wasn't sure if it answered my question as the person did this in threads which I am not familiar with how to implement. Apologies if I dont seem to have the logic correct - so please advise otherwise.
Looks fairly standard, except I would simplify it by keeping two keyboard state variables declared as class variables, like:
const Uint8 *curKeys = SDL_GetKeyboardState(NULL), *prevKeys;
// ...
void Game::update() {
prevKeys = curKeys;
curKeys = = SDL_GetKeyboardState(NULL);
//and so then compare curKeys to prevkeys
//and ditch the booleans
// ...
}
I'm making a thread software with VTK, where I need to change the model itself in real time, while I need to change his method of rendering. Everything is working fine, but, the problem start with the interactor->start(); , the model data gets updated just fine, but it's only showed on screen when I move The camera. Also I have selected some methods for generating a 3D data from a imagedata file, for that I need to close the vtk window (interactor window) and then the code will reopen it and send the new data generated to it...
I would need something like these:
int force close_window = false; int refresh_interactor = false;
I managed to make the Window close, but only with vtkcommand::Keypressed command, but idk how do I do with a new command :S, I tried the vtkcommand::UserEvent but I didn't found a good information about how to deal with that data (like some way to call it)
the way I'm dealing with VTK is with two threads, the first one, is just about the vtk iren loop, and the second one would manage the models and check if iren requires to be updated.
In my dream code it should be something like this:
=======================================================
bool VTKWindow()
{
...
vtkSmartPointer ator = vtkSmartPointer::New();
iren = vtkSmartPointer::New();
RenWindow = vtkSmartPointer::New();
render->SetBackground(.1, .2, .3);
RenWindow->AddRenderer(renderer);
iren->SetRenderWindow(RenWindow);
if(data_type == voxel_type)
{
Render->AddViewProp(VoxelData);
}
else
{
actor->SetMapper(PolyData);
Render->AddActor(Actor);
}
RenWindow->Render();
iren->Start();
}
void ManageVTK()
{
while true loop...
if(force close_window == true)
do some command to exit the iren loop
if(refresh_interactor == true)
do some command to refresh iren
}
Sorry for the english, it's not my native language, and also sorry about the question format, it's the first time I'm using stackoverflow
It may sounds stupid, but, I found a kind of solution for the problem.
I saw on related links this guy vtkRenderWindowInteractor event loop and threading and, it's almost the same problem...
class VTKNewEvent : public vtkCommand{
public:
vtkTypeMacro(VTKNewEvent , vtkCommand);
static VTKNewEvent * New(){
return new VTKNewEvent ;
}
void Execute(vtkObject * caller, unsigned long vtkNotUsed(eventId), void * vtkNotUsed(callData)){
vtkRenderWindowInteractor *iren = static_cast<vtkRenderWindowInteractor*>(caller);
if (iren_close == true){
iren->GetRenderWindow()->Finalize // Stop the interactor
iren->TerminateApp();
iren_close = false;
}
if (iren_update== true){
renderJanela->Render();
iren_update= false;
}
}
};
bool VTKWindow(){
vtkSmartPointer<VTKNewEvent > IrenRefresh= vtkSmartPointer<VTKNewEvent>::New();
...
iren->CreateRepeatingTimer(1);//this makes that IrenRefresh will be called at every 1ms
iren->AddObserver(vtkCommand::TimerEvent, IrenRefresh);
iren->Start();
...
}
it's simple, but, maybe not the best, but it did Th job, I hope this link will help people that are starting into the VTK world, since threads + rendering loop wasn't a simple job to understand what was going on
I'm grabbing Alt+Space global hotkey using xcb_grab_key, as follows:
xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c);
xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space), keycode;
// add bindings for all screens
xcb_screen_iterator_t iter;
iter = xcb_setup_roots_iterator (xcb_get_setup (c));
for (; iter.rem; xcb_screen_next (&iter)) {
int i = 0;
while(keycodes[i] != XCB_NO_SYMBOL) {
keycode = keycodes[i];
xcb_grab_key(c, true, iter.data->root, XCB_MOD_MASK_ANY, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
i += 1;
}
}
Then in Qt's QAbstractNativeEventFilter subclass I process it and emit a Qt signal if key matches Alt+Space:
xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space);
int i = 0;
bool found = false;
while(keycodes[i] != XCB_NO_SYMBOL) {
if(event->detail == keycodes[i]) {
if(event->state & GetModifier(c, keysyms, XK_Alt_L) || event->state & GetModifier(c, keysyms, XK_Alt_R)) {
xcb_allow_events(c, XCB_ALLOW_ASYNC_KEYBOARD, event->time);
emit gotHotKey();
found = true;
} else {
xcb_allow_events(c, XCB_ALLOW_REPLAY_KEYBOARD, event->time);
}
break;
}
i += 1;
}
if(found) return true;
(GetModifier is copied from VLC but I think this part doesn't matter since Alt-key is matched correctly)
The problem I'm having is that after show()ing main window when the hotkey is pressed, keyboard is most of the times1 not focused properly. I can type, but the cursor is not visible, input's border is not highlighted, and the shortcut Ctrl+Q for quitting desn't work. It can be worked around by moving the window, or pressing space - then focus is restored - cursor+border reappears and Ctrl+Q works. What might be causing this behaviour?
I'm using Qt 5.0.0 and xcb 1.8.1. Complete application can be downloaded for compiling from github.
1 it means sometimes the issue is not reproducible - focus is set correctly even for repeated window hide/shows, but then other times it happens multiple times in a row of hide/shows. It occurs more often than not overall.
(Edit: I've implemented a (very ugly...) workaround, so to reproduce the issue for the github project, the following code needs to be removed)
#ifndef WIN32
// Very ugly workaround for the problem described at http://stackoverflow.com/questions/14553810/
// (just show and hide a modal dialog box, which for some reason restores proper keyboard focus)
hackDialog.setGeometry(0, 0, 0, 0);
hackDialog.setModal(true);
hackDialog.show();
QTimer::singleShot(100, &hackDialog, SLOT(reject()));
#endif