Jump to content
  • Advertisement
Sign in to follow this  
war3cadu12

Problem with String Input using SDL

This topic is 2608 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am new this forum and I have problem with input

It is hard to fix it string input any keys and I've not have ideas to fix "~~ ~ " ' ! @ # $ % ¨¨ & * ( ) _ + { } [ ] ´ / ; ? . , > < " etc. Becuase I want make login for online.

Thank you for the help.

Share this post


Link to post
Share on other sites
Advertisement
Your question is very unclear. I assume your problem is related to translating SDL_KeyboardEvents into text. You can enable unicode translation at the start of your program, using SDL_EnableUNICODE(SDL_TRUE). You can then inspect event.key.keysym.unicode and get the text from it.

Here is a function I have used in the past for this:

char getUnicodeValue( const SDL_KeyboardEvent &key )
{
// magic numbers courtesy of SDL docs :)
const int INTERNATIONAL_MASK = 0xFF80;
const int UNICODE_MASK = 0x7F;

int uni = key.keysym.unicode;
if( uni == 0 ) // not translatable key (like up or down arrows)
{
// probably not useful as string input
// we could optionally use this to get some value
// for it: SDL_GetKeyName( key );
return '\0';
}
if( ( uni & INTERNATIONAL_MASK ) == 0 )
{
if( SDL_GetModState() & KMOD_SHIFT )
{
return (char)(toupper(uni & UNICODE_MASK));
}
else
{
return (char)(uni & UNICODE_MASK);
}
}
else // we have a funky international character. one we can't read :(
{
// we could do nothing, or we can just show some sign of input, like so:
return '?';
}
}

You can then append this character to a std::string instance, provided it is not the NUL character (the character literal '\0').

Share this post


Link to post
Share on other sites
You still aren't explaining your problem well. What is the program supposed to be doing? What is it actually doing? Can you post your code? Or a minimal example that demonstrates the behaviour?

Share this post


Link to post
Share on other sites
Here is my code:


#pragma warning( disable : 4800 )

#ifdef main
#undef main
#endif

#include "functions.h"
#include "keyboard.h"

#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "SDL_resize.h"
//#include "SDL_net.h"

#include "tchar.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <direct.h>

#include "IniWriter.h"
#include "IniReader.h"

#define DEBUG

using namespace std;

SDL_Surface *screen = NULL;

SDL_Surface *onMainBG = NULL;
SDL_Surface *onLoginTB = NULL;
SDL_Surface *onPasswordTB = NULL;

int modeX;
int modeY;
bool fullscreenS;
bool isDefaultSettingsResolution;
Uint8* keyboard;

SDL_Event event;

bool running;

/*

List of credits:
• xiaohe521 - IniWriter and IniReader
• rip-off - Helper
• http://www.freeimages.co.uk/ - Images
• http://www.libsdl.org/ - SDL and SDL_Resize
• http://www.zedwood.com/ - MD5 function

*/

char getUnicodeValue( const SDL_KeyboardEvent &key )
{
// magic numbers courtesy of SDL docs :)
const int INTERNATIONAL_MASK = 0xFF80;
const int UNICODE_MASK = 0x7F;

int uni = key.keysym.unicode;
if( uni == 0 ) // not translatable key (like up or down arrows)
{
// probably not useful as string input
// we could optionally use this to get some value
// for it: SDL_GetKeyName( key );
return '\0';
}
if( ( uni & INTERNATIONAL_MASK ) == 0 )
{
if( SDL_GetModState() & KMOD_SHIFT )
{
return (char)(toupper(uni & UNICODE_MASK));
}
else
{
return (char)(uni & UNICODE_MASK);
}
}
else // we have a funky international character. one we can't read :(
{
// we could do nothing, or we can just show some sign of input, like so:
return '?';
}
}

void onLoadFiles()
{
onMainBG = LImage(".\\data\\main\\bg.png");

if (isDefaultSettingsResolution == false)
{
SDL_Resize(onMainBG, modeX, modeY, screen, 4);
}
}

int main( int argc, char* args[] )
{
ifstream CheckFile(".\\settings.ini");

if ( !CheckFile.is_open() )
{
int msok = MessageBox(NULL, "Can't find \"settings.ini\".", "Error", MB_OK | MB_ICONQUESTION );
if ( msok )
{
int msyesno = MessageBox(NULL, "Do you want create settings?", "Request", MB_YESNOCANCEL | MB_ICONQUESTION );
if ( msyesno == 6 )
{
ofstream CheckFile(".\\settings.ini");
CheckFile << "[Graphics]\n";
CheckFile << "ResolutionX=800\n";
CheckFile << "ResolutionY=600\n";
CheckFile << "Fullscreen=false\n";
}
else
{
return 1;
}
}
}

CIniReader iniReader(".\\settings.ini");
modeX = iniReader.ReadInteger("Graphics", "ResolutionX", 800);
modeY = iniReader.ReadInteger("Graphics", "ResolutionY", 600);
fullscreenS = iniReader.ReadBoolean("Graphics", "Fullscreen", true);

if (modeX == 800 || modeY == 600) { isDefaultSettingsResolution = true; }
else { isDefaultSettingsResolution = false; }

if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
MessageBox( NULL, "Can't run this game." , "ERROR", MB_OK | MB_ICONERROR );
return 1;
}
else
{
SDL_WM_SetCaption( "The RPG", NULL );
SDL_WM_SetIcon( IMG_Load(".\\icon.ico"), NULL );
showMouse(false);
if (fullscreenS == true) { screen = SDL_SetVideoMode( modeX, modeY, 32, SDL_SWSURFACE|SDL_FULLSCREEN ); }
else { screen = SDL_SetVideoMode( modeX, modeY, 32, SDL_SWSURFACE ); }
if ( screen == NULL ) { MessageBox( NULL, "Can't create windows.", "Error", MB_OK | MB_ICONERROR ); return 1; }
if ( TTF_Init() == -1 ) { return 1; }
}

const int FPS=30;
Uint32 StartFPS;
int testi = 0;
string keystring;



onLoadFiles();
SDL_EnableUNICODE( SDL_TRUE );

running = true;

while( running )
{
StartFPS = SDL_GetTicks();
while( SDL_PollEvent( &event ) )
{

switch ( event.type )
{
case SDL_QUIT:
running = false;

case SDL_KEYUP:
switch ( event.key.state )
{
case SDL_RELEASED:
switch ( event.key.keysym.sym )
{
case SDLK_LSHIFT:
SDL_CapsLock(false);
case SDLK_RSHIFT:
SDL_CapsLock(false);
}
}
case SDL_KEYDOWN:

keystring += getUnicodeValue(event.key);

switch ( event.key.keysym.sym )
{
case SDLK_ESCAPE:
running = false;
}
switch ( event.key.state )
{
case SDL_PRESSED:

switch ( event.key.keysym.sym )
{
case SDLK_LSHIFT:
SDL_CapsLock(true);
case SDLK_RSHIFT:
SDL_CapsLock(true);
}

}
}
}

SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff) );

drawImage(0, 0, onMainBG, screen, NULL);

drawText(0, 255, 0, 255, IntToString(testi), ".\\data\\font\\font3.fon", "center", 32, 100, 0, screen);
drawText(0, 255, 0, 255, keystring, ".\\data\\font\\font3.fon", "center", 32, 100, 20, screen);




if( SDL_Flip( screen ) == -1 ) { return 1; }
if( 1000/FPS>(SDL_GetTicks()-StartFPS) ) { SDL_Delay(1000/FPS-(SDL_GetTicks()-StartFPS)); }
}

SDL_FreeSurface(onMainBG);
SDL_Quit();
return 0;
}

Share this post


Link to post
Share on other sites
There are some bugs in your code. The main one is that your switch statements don't contain "break" statements - which results in far more code being executed for each event.

You also don't check the return value of getUnicodeValue(), which returns the NUL character (0 or '\0') when it encounters a non-textual character.

Here is a small program demonstrating how to use it. It uses the window caption to display the text:

#include "SDL.h"

#include <iostream>
#include <string>

char getUnicodeValue( const SDL_KeyboardEvent &key )
{
// magic numbers courtesy of SDL docs :)
const int INTERNATIONAL_MASK = 0xFF80;
const int UNICODE_MASK = 0x7F;

int uni = key.keysym.unicode;
if( uni == 0 ) // not translatable key (like up or down arrows)
{
// probably not useful as string input
// we could optionally use this to get some value
// for it: SDL_GetKeyName( key );
return '\0';
}
if( ( uni & INTERNATIONAL_MASK ) == 0 )
{
if( SDL_GetModState() & KMOD_SHIFT )
{
return (char)(toupper(uni & UNICODE_MASK));
}
else
{
return (char)(uni & UNICODE_MASK);
}
}
else // we have a funky international character. one we can't read :(
{
// we could do nothing, or we can just show some sign of input, like so:
return '?';
}
}

int main( int argc, char* args[] )
{
int modeX = 800;
int modeY = 600;
bool fullscreen = false;

if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
std::cerr << "Failed to initialise SDL: " << SDL_GetError() << '\n';
return 1;
}

Uint32 flags = fullscreen ? SDL_FULLSCREEN : SDL_SWSURFACE;
SDL_Surface *screen = SDL_SetVideoMode( modeX, modeY, 32, flags);

if (!screen)
{
std::cerr << "Failed to set video mode: " << SDL_GetError() << '\n';
return 1;
}

std::string keystring;

SDL_EnableUNICODE( SDL_TRUE );

bool running = true;
SDL_Event event;
while( running )
{
while( SDL_PollEvent( &event ) )
{
switch ( event.type )
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch ( event.key.keysym.sym )
{
case SDLK_ESCAPE:
running = false;
break;

case SDLK_BACKSPACE:
if(!keystring.empty())
{
keystring.erase(keystring.end() - 1);
}
break;

case SDLK_RETURN:
keystring.erase(keystring.begin(), keystring.end());
break;

default:
char key = getUnicodeValue(event.key);
if(key != '\0')
{
keystring += key;
}
break;
}
}
}

SDL_FillRect( screen, NULL, 0);
const char *title = keystring.empty() ? "(no input)" : keystring.c_str();
SDL_WM_SetCaption(title, NULL);
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}

SDL_Quit();
return 0;
}

Again, you haven't really describe what is or isn't happening. I had to distill the likely problems from examining the source, and refining it into a minimal example. Your example had too many dependencies to be considered minimal.

Not everyone would go to this amount of effort to help you out. Not everyone would have time to. I would seriously suggest you consider making more of an effort to clearly and concisely explain the problems you have.

Share this post


Link to post
Share on other sites
Wow, thank you very much. I forget about break; and I didnt know there is flags "Uint32"

You'll be added credis

EDIT:
How do i give you a +rep?

Share this post


Link to post
Share on other sites
If I tell you will you give me one?

Hit the Like This button in the lower-right of the post.


L. Spiro


P.S.: I was joking about giving me one.

Share this post


Link to post
Share on other sites
Thanks[color="#B57438"] YogurtEmperor[color="#000000"].

One more,

Is there fix for "¹²³£¢¬" ?

Sorry for the stupid questions again.

Edit:
Again is there no "é è ã â ê ê `` ´´" ;(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!