質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.58%

SDL2で日本語を表示することができない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,295

score 31

前提・実現したいこと

SDL2でゲームを作っていたのですが、メッセージを表示する機能を実装中に以下のエラーが発生しました。

発生している問題・エラーメッセージ

日本語を入力すると文字化けしてしまいます。
英語ではできました。
]
イメージ説明

該当のソースコード

#include "SDL2/SDL.h"
#include "SDL2/SDL_image.h"
#include "SDL2/SDL_ttf.h"

typedef struct
{
    SDL_Surface *image_f, *image_b, *image_r, *image_l;
    SDL_Rect rect, rect_pos, rect_tmp;
    SDL_Texture *texture_f, *texture_b, *texture_r, *texture_l;
    SDL_Texture *texture_use;
    int direction;
} layer_dir;

typedef struct
{
    SDL_Surface *image_small, *image_middle, *image_large;
    SDL_Rect rect, rect_pos, rect_tmp;
    SDL_Texture *texture_small, *texture_middle, *texture_large;
    SDL_Texture *texture_use;
} layer_ani;

int Object[27][15] = {
    {0, 0},
    {0, 0}};

int GetPos(SDL_Rect *from, SDL_Rect *to)
{
    to->x = from->x * 23;
    to->y = from->y * 31;
    return 0;
}

void maketex_dir(layer_dir *, SDL_Renderer *);
void maketex_ani(layer_ani *undefined, SDL_Renderer *renderer);

void LoadIMG_dir(const char front[20], const char back[20], const char right[20], const char left[20], layer_dir *undefined);
void LoadIMG_ani(const char small[20], const char middle[20], const char large[20], layer_ani *undefined);

void OpenBox(SDL_Renderer *);
void PrintText(SDL_Renderer *, const char *, TTF_Font *, SDL_Color color);

void destex_dir(layer_dir *);
void destex_ani(layer_ani *);

int main(int argc, const char *argv[])
{
    SDL_Window *Window;
    SDL_Renderer *renderer;

    int isFinish = 0;
    int img = 0;
    int scene = 1;
    int Box = 0;
    int msg = 0;

    layer_dir charcter;

    layer_ani enemy;

    TTF_Font *font;
    SDL_Color white = {255, 255, 0, 255};

    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();

    Window = SDL_CreateWindow("Key", 0, 0, 640, 480, SDL_WINDOW_SHOWN);

    font = TTF_OpenFont("rounded-x-mplus-1c-black.ttf", 24);

    renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

    LoadIMG_dir("char/front.png", "char/back.png", "char/right.png", "char/left.png", &charcter);
    LoadIMG_ani("enemy/small.png", "enemy/middle.png", "enemy/large.png", &enemy);

    charcter.rect.x = 2;
    charcter.rect.y = 0;
    charcter.rect.w = charcter.image_f->w;
    charcter.rect.h = charcter.image_f->h;

    enemy.rect.x = 0;
    enemy.rect.y = 0;
    enemy.rect.h = enemy.image_small->h;
    enemy.rect.w = enemy.image_small->w;

    maketex_ani(&enemy, renderer);
    maketex_dir(&charcter, renderer);

    Object[0][0] = 1;
    Object[0][1] = 1;

    charcter.texture_use = charcter.texture_f;
    enemy.texture_use = enemy.texture_small;

    charcter.rect_pos = charcter.rect;
    charcter.rect_tmp = charcter.rect;

    enemy.rect_pos = enemy.rect;
    while (isFinish == 0)
    {

        SDL_Event event;

        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_KEYDOWN:
            {
                switch (event.key.keysym.sym)
                {
                case SDLK_UP:
                    charcter.rect_tmp.y -= 1;
                    charcter.texture_use = charcter.texture_b;
                    break;

                case SDLK_DOWN:
                    charcter.rect_tmp.y += 1;
                    charcter.texture_use = charcter.texture_f;
                    break;

                case SDLK_RIGHT:
                    charcter.rect_tmp.x += 1;
                    charcter.texture_use = charcter.texture_r;
                    break;

                case SDLK_LEFT:
                    charcter.rect_tmp.x -= 1;
                    charcter.texture_use = charcter.texture_l;
                    break;

                case SDLK_ESCAPE:
                    isFinish = 1;
                    break;

                case SDLK_SPACE:
                    if (Box == 0)
                    {
                        Box = 1;
                    }
                    else
                    {
                        Box = 0;
                    }

                    if (msg == 0)
                    {
                        msg = 1;
                    }
                    else
                    {
                        msg = 0;
                    }
                    break;
                }
            }
            }

            if (charcter.rect_tmp.y < 0 ||
                charcter.rect_tmp.y > 14 ||
                charcter.rect_tmp.x < 0 ||
                charcter.rect_tmp.x > 26 ||
                Object[charcter.rect_tmp.y][charcter.rect_tmp.x] == 1)
            {
                charcter.rect_tmp = charcter.rect;
            }
            else
            {
                charcter.rect = charcter.rect_tmp;
            }

            GetPos(&charcter.rect, &charcter.rect_pos);
        }

        if (img < 500)
        {
            enemy.texture_use = enemy.texture_small;
        }
        else if (img < 1000)
        {
            enemy.texture_use = enemy.texture_middle;
        }
        else if (img < 1500)
        {
            enemy.texture_use = enemy.texture_large;
        }
        else
        {
            img = 0;
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, charcter.texture_use, NULL, &charcter.rect_pos);
        SDL_RenderCopy(renderer, enemy.texture_use, NULL, &enemy.rect_pos);

        if (Box == 1)
        {
            OpenBox(renderer);
        }

        switch (msg)
        {
        case 1:
            PrintText(renderer, u8"あいうえお", font, white);
            break;

        default:
            break;
        }

        img++;
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyRenderer(renderer);
    destex_ani(&enemy);
    destex_dir(&charcter);
    SDL_DestroyWindow(Window);

    SDL_Quit();

    return 0;
}

void maketex_dir(layer_dir *undefined, SDL_Renderer *renderer)
{
    undefined->texture_f = SDL_CreateTextureFromSurface(renderer, undefined->image_f);
    undefined->texture_b = SDL_CreateTextureFromSurface(renderer, undefined->image_b);
    undefined->texture_r = SDL_CreateTextureFromSurface(renderer, undefined->image_r);
    undefined->texture_l = SDL_CreateTextureFromSurface(renderer, undefined->image_l);

    SDL_FreeSurface(undefined->image_f);
    SDL_FreeSurface(undefined->image_b);
    SDL_FreeSurface(undefined->image_r);
    SDL_FreeSurface(undefined->image_l);
}

void LoadIMG_dir(const char front[20], const char back[20], const char right[20], const char left[20], layer_dir *undefined)
{
    undefined->image_f = IMG_Load(front);
    undefined->image_b = IMG_Load(back);
    undefined->image_r = IMG_Load(right);
    undefined->image_l = IMG_Load(left);
}

void maketex_ani(layer_ani *undefined, SDL_Renderer *renderer)
{
    undefined->texture_small = SDL_CreateTextureFromSurface(renderer, undefined->image_small);
    undefined->texture_middle = SDL_CreateTextureFromSurface(renderer, undefined->image_middle);
    undefined->texture_large = SDL_CreateTextureFromSurface(renderer, undefined->image_large);

    SDL_FreeSurface(undefined->image_small);
    SDL_FreeSurface(undefined->image_middle);
    SDL_FreeSurface(undefined->image_large);
}

void LoadIMG_ani(const char small[20], const char middle[20], const char large[20], layer_ani *undefined)
{

    undefined->image_small = IMG_Load(small);
    undefined->image_middle = IMG_Load(middle);
    undefined->image_large = IMG_Load(large);
}

void OpenBox(SDL_Renderer *renderer)
{
    SDL_Surface *surface = SDL_CreateRGBSurface(0, 608, 128, 32, 0, 0, 0, 255);
    SDL_Texture *texture;
    SDL_Rect rect;

    rect.h = surface->h;
    rect.w = surface->w;
    rect.x = 16;
    rect.y = 320;

    texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);

    SDL_RenderCopy(renderer, texture, NULL, &rect);
}

void PrintText(SDL_Renderer *renderer, const char *text, TTF_Font *font, SDL_Color color)
{
    SDL_Surface *surface = TTF_RenderText_Blended(font, text, color);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_Rect rect;

    rect.h = surface->h;
    rect.w = surface->w;
    rect.x = 16;
    rect.y = 320;

    SDL_FreeSurface(surface);
    SDL_RenderCopy(renderer, texture, NULL, &rect);
}

void destex_dir(layer_dir *layer)
{

    SDL_DestroyTexture(layer->texture_f);
    SDL_DestroyTexture(layer->texture_b);
    SDL_DestroyTexture(layer->texture_r);
    SDL_DestroyTexture(layer->texture_l);
    SDL_DestroyTexture(layer->texture_use);
}

void destex_ani(layer_ani *layer)
{

    SDL_DestroyTexture(layer->texture_small);
    SDL_DestroyTexture(layer->texture_middle);
    SDL_DestroyTexture(layer->texture_large);
    SDL_DestroyTexture(layer->texture_use);
}

試したこと

関数化せず、main関数の中で処理を行っても同様の結果となりました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

SDLはよく知りませんが、リファレンスマニュアルを見ると、

TTF_RenderText_Blended - LATIN1テキストを混合モードで描く
TTF_RenderUTF8_Blended - UTF8テキストを混合モードで描く

だそうです。
「latin1」とは主にヨーロッパ言語の文字コードですから、日本語は含みません。
使うのは「TTF_RenderUTF8_Blended」ではないですか。

もちろん、

  • フォントに日本語が含まれているか。(ファイル名からして、mplusの派生フォントだろうから問題はないだろうけど)
  • 渡す文字列がUTF8か。

も確認してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/24 09:36

    回答ありがとうございます。
    無事解決しました。APIが違っていたのですね...

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る