落書きノート

ふと自分が気になった事を書いてます

C/C++とSDL2でアイデアが出たが失敗

前記事の続きです。アイデアが出てやってみましたがやっぱり無理でした。ソースからカスタマイズしていかないと無理だと思います。試したソースコードはこんな感じです。これで最後にします。次回以降からはAndroidスマホ)のプログラムを作っていく予定です。JavaOpenGL ESを使って3D視点移動から作っていこうかと。スマホの新調、Nexus 5XかiPhone 6、どちらにしよう。

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
std::vector<std::string> eachChar(std::string str);
void render();
void drawMessageWindow();
void drawString();
bool init();
bool loadMedia();
void close();
SDL_Window *gWindow = NULL;
SDL_Renderer *gRenderer = NULL;
SDL_Surface *gHelloWorld = NULL;
SDL_Texture *gHelloWorldTexture = NULL;
SDL_Surface *gTextSurface = NULL;
SDL_Texture *gStringTexture = NULL;
SDL_Event event;
bool done = false;
const std::string gfontName = "TakaoGothic.ttf";
const int gfontSize = 32;
TTF_Font *gFont;
SDL_Rect gRenderStringPosition;
SDL_Rect gMessageRect;

std::vector<std::string> eachChar(std::string str)
{
  std::vector<std::string> result;
  int pos;
  unsigned char lead;
  int char_size;
  int charNum = 0;
  int i;
  for (pos = 0, i = 0; pos < str.length(); pos += char_size, i++) {
    charNum++;
    lead = str[pos];
    if (lead < 128) {
      char_size = 1;
    } else if (lead < 224) {
      char_size = 2;
    } else if (lead < 240) {
      char_size = 3;
    } else {
      char_size = 4;
    }
    
    result.push_back(str.substr(pos, char_size).c_str());
  }

  return result;
}
  
void render()
{
  SDL_RenderClear(gRenderer);
  SDL_RenderCopy(gRenderer, gHelloWorldTexture, NULL, NULL);
  SDL_SetRenderDrawBlendMode(gRenderer, SDL_BLENDMODE_BLEND);
  SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 128);
  SDL_RenderFillRect(gRenderer, &gMessageRect);
}

void drawMessageWindow() {
  SDL_Rect messageRect = { 30, 300, SCREEN_WIDTH - 60, SCREEN_HEIGHT - 320 };
  gMessageRect = messageRect;
}

void drawString()
{
  int w, h;
  int dw = 40;
  int counter = 0;
  std::vector<std::string> strArray;
  std::string str;
  std::ifstream ifs("test.txt");
  if(!ifs) {
    std::cerr << "File Read Error!" << std::endl;
    std::exit(EXIT_FAILURE);
  }
  while(getline(ifs, str)) {
    strArray = eachChar(str);
    for(int i = 0; i < strArray[0].length(); i++) {
      gTextSurface = TTF_RenderUTF8_Blended(gFont,
                                            strArray[i].c_str(),
                                            (SDL_Color) { 255, 255, 255, 128 });
      TTF_SizeUTF8(gFont, strArray[i].c_str(), &w, &h);
      dw = dw + w;
      gStringTexture = SDL_CreateTextureFromSurface(gRenderer, gTextSurface);
      gRenderStringPosition = (SDL_Rect) { dw, 310, gTextSurface->w, gTextSurface->h };
      SDL_RenderCopy(gRenderer, gStringTexture, NULL, &gRenderStringPosition);
      for(int j = 0; j <= 50; j++)
        counter++;
    }
  }
}

bool init()
{
  bool success = true;
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
    printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
    success = false;
  } else {
    SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_RESIZABLE, &gWindow, &gRenderer);
    if(gWindow == NULL || gRenderer == NULL) {
      printf( "Window and Renderer could not be created! SDL_Error: %s\n", SDL_GetError() );
      success = false;
    }
  }

  SDL_SetWindowTitle(gWindow, "Test Game");
  TTF_Init();
  gFont = TTF_OpenFont(gfontName.c_str(), gfontSize);
  
  return success;
}

bool loadMedia()
{
  bool success = true;
  gHelloWorld = SDL_LoadBMP("./hello_world.bmp");
  if( gHelloWorld == NULL )
    {
      printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
      success = false;
    }
  gHelloWorldTexture = SDL_CreateTextureFromSurface(gRenderer, gHelloWorld);
  if(gHelloWorldTexture == NULL)
    {
      printf("Unable to load Texture! SDL Error: %s\n", SDL_GetError());
      success = false;
    }
  return success;
}

void close()
{
  SDL_FreeSurface(gHelloWorld);
  SDL_FreeSurface(gTextSurface);
  SDL_DestroyTexture(gHelloWorldTexture);
  SDL_DestroyTexture(gStringTexture);
  SDL_DestroyRenderer(gRenderer);
  SDL_DestroyWindow(gWindow);
  SDL_Quit();
  TTF_CloseFont(gFont);
  TTF_Quit();
}

int main( int argc, char* args[] )
{
  if(!init()) {
    printf( "Failed to initialize!\n" );
  } else {
    if(!loadMedia()) {
      printf( "Failed to load media!\n" );
    }
    else {
      while(!done) {
        while(SDL_PollEvent(&event)) {
          switch(event.type) {
          case SDL_KEYDOWN:
            if(event.key.keysym.sym == SDLK_ESCAPE) {
              done = true;
            }
            break;
          case SDL_QUIT:
            done = true;
            break;
          }
          drawMessageWindow();
          render();
          drawString();
          SDL_RenderPresent(gRenderer);
        }
      }
    }
  }
  
  close();
  
  return 0;
}