【WinRT】GameMainを作ってみる

DirectXは仮でどのように作成するかを確認しただけなので、いったん削除して今度は受け取り用のGameMainClassを作ってみる。

ひとまず、サンプルを見つつ「sample3DGameDX」を分解しつつ勉強中。surfaceなどのパッド系は考えていないのでOrientationは必要か怪しいけどとりあえず書いておく。

#pragma once

#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.ApplicationModel.Core.h>
#include <winrt/Windows.UI.Core.h>


class GameMain : public winrt::implements<GameMain, winrt::Windows::Foundation::IInspectable>
{
public:

	GameMain();
	virtual ~GameMain();

	void Run();

	void Close();

	void Suspend();

	void Resume();

	void Visibility(bool visible);

private:
	bool m_windowClosed;
	bool m_visible;

	winrt::agile_ref<winrt::Windows::UI::Core::CoreWindow> m_window;

};
#include "pch.h"

using namespace winrt;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::UI::Core;

GameMain::GameMain()
	: m_windowClosed(false)
	, m_visible(false)
{
}

GameMain::~GameMain()
{
}

void GameMain::Run()
{
	while (!m_windowClosed)
	{
		if (m_visible)
		{
			CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
		}
		else
		{
			CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
		}
	}
}

void GameMain::Close()
{
	m_windowClosed = true;
}

void GameMain::Suspend()
{
}

void GameMain::Resume()
{
}

void GameMain::Visibility(bool visible)
{
	if (visible && !m_visible)
	{
		
	}
	m_visible = visible;
}
#pragma once
#include <windows.h>
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.Core.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/Windows.UI.Composition.h>
#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.Graphics.Display.Core.h>

#include "GameMain/GameMain.h"
#include "pch.h"

using namespace winrt;
using namespace Windows;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;
using namespace Windows::UI::Input;
using namespace Windows::Graphics::Display;

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
	IFrameworkView CreateView()
	{
		return *this;
	}

	// This method is called on application launch.
	void Initialize(CoreApplicationView const& applicationView)
	{
		applicationView.Activated({ this, &App::OnActivated });

		CoreApplication::Suspending({this, &App::OnSuspending });

		CoreApplication::Resuming({ this, &App::OnResuming });

		// DeviceResourceの作成(DirectXなど)
	}

	void Load(winrt::hstring const& /*entryPoint*/)
	{
		if (!m_gameMain)
		{
			m_gameMain = winrt::make_self<GameMain>();
		}
	}

	void OnActivated(CoreApplicationView const& /* applicationView */, IActivatedEventArgs const& /* args */)
	{
		// Activate the application window, making it visible and enabling it to receive events.
		CoreWindow::GetForCurrentThread().Activate();
	}

	winrt::fire_and_forget OnSuspending(IInspectable const& /* sender */, SuspendingEventArgs const& args)
	{
		auto lifetime = get_strong();

		SuspendingDeferral deferral = args.SuspendingOperation().GetDeferral();

		co_await winrt::resume_background();

		m_gameMain->Suspend();

		deferral.Complete();
	}

	void OnResuming(IInspectable const& /* sender */, IInspectable const& /* args */)
	{
		m_gameMain->Resume();
	}

	// This method is called after Load.
	void Run()
	{
		m_gameMain->Run();
	}

	// This method is called after Initialize.
	void SetWindow(CoreWindow const& window)
	{
		window.PointerCursor(CoreCursor(CoreCursorType::Arrow, 0));

		PointerVisualizationSettings visualizationSettings{ PointerVisualizationSettings::GetForCurrentView() };
		visualizationSettings.IsContactFeedbackEnabled(false);
		visualizationSettings.IsBarrelButtonFeedbackEnabled(false);

		window.Activated({ this, &App::OnWindowActivationChanged });

		window.SizeChanged({ this, &App::OnWindowSizeChanged });

		window.Closed({ this, &App::OnWindowClosed });

		window.VisibilityChanged({ this, &App::OnVisibilityChanged });

		DisplayInformation currentDisplayInformation{ DisplayInformation::GetForCurrentView() };

		currentDisplayInformation.DpiChanged({ this, &App::OnDpiChanged });

		currentDisplayInformation.OrientationChanged({ this, &App::OnOrientationChanged });

		currentDisplayInformation.StereoEnabledChanged({this, &App::OnStereoEnabledChanged});

		DisplayInformation::DisplayContentsInvalidated({ this, &App::OnDisplayContentsInvalidated });
	}

	// This method is called before the application exits.
	void Uninitialize()
	{
	}

private:

	void OnWindowActivationChanged(CoreWindow const& /* sender */, WindowActivatedEventArgs const& args)
	{
		CoreWindow::GetForCurrentThread().Activate();
	}

	void OnWindowSizeChanged(CoreWindow const& /* sender */, WindowSizeChangedEventArgs const &args)
	{
		/* ウィンドウのサイズが変化した時に呼び出される */
	}

	void OnWindowClosed(CoreWindow const& /* sender */, CoreWindowEventArgs const& args)
	{
		m_gameMain->Close();
	}

	void OnVisibilityChanged(CoreWindow const& /* sender */, VisibilityChangedEventArgs const& args)
	{
		/* ウィンドウの表示状態が変わった時に呼び出される */
	}

	void OnDpiChanged(DisplayInformation const& /* sender */, IInspectable const& /* args */)
	{
		/* 解像度変更が発生した時に呼び出される */
	}

	void OnOrientationChanged(DisplayInformation const& sender, IInspectable const& /* args */ )
	{
		/* 縦横変わった時に来る - Windowsで使用する場合は必要ない */
	}

	void OnStereoEnabledChanged(DisplayInformation const& /* sender */, IInspectable const& /* args */)
	{
		/* サウンド関係?変更時 */
	}

	void OnDisplayContentsInvalidated(DisplayInformation const& /* sender */, IInspectable const& /* args */)
	{
		/* コンテンツが非有効になった場合 */
	}

private:

	winrt::com_ptr<GameMain> m_gameMain;

};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
	CoreApplication::Run(make<App>());
}

だいぶん、スッキリ。テキストを見る感じIInspectableがいわゆるSystem.Objectと似た概念らしい。継承させることでcom_ptrで使用する事ができるみたいで便利。
多分オブジェクト管理したいときに継承させるみたい。

次はDeviceResourceのクラスを作ってそっちもつなげてみようと思う。

【WinRT】DirectXの作成

ひとまず、IFrameworkViewの初期化に関するページから抜粋しながら作成。

ちなみに、下記ページからコピペしています。

https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.core.iframeworkview?view=winrt-19041

void Initialize(CoreApplicationView const& applicationView)
{
    applicationView.Activated({ this, &App::OnActivated });
}
public:
    void OnActivated(CoreApplicationView const& /* applicationView */, IActivatedEventArgs const& /* args */)
    {
        // Activate the application window, making it visible and enabling it to receive events.
        CoreWindow::GetForCurrentThread().Activate();
    }

private:
    void OnWindowSizeChanged(CoreWindow const& /*sender*/, WindowSizeChangedEventArgs const& /* args */)
    {
        m_renderTargetView = nullptr;
        CreateWindowSizeDependentResources();
    }
    void Run()
    {
        // First, create the Direct3D device.

        // This flag is required in order to enable compatibility with Direct2D.
        UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#if defined(_DEBUG)
        // If the project is in a debug build, enable debugging via SDK Layers with this flag.
        creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

        // This array defines the ordering of feature levels that D3D should attempt to create.
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_1,
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
            D3D_FEATURE_LEVEL_9_3,
            D3D_FEATURE_LEVEL_9_1
        };

        winrt::com_ptr<ID3D11Device> d3dDevice;
        winrt::com_ptr<ID3D11DeviceContext> d3dDeviceContext;
        winrt::check_hresult(
            ::D3D11CreateDevice(
                nullptr,                    // specify nullptr to use the default adapter
                D3D_DRIVER_TYPE_HARDWARE,
                nullptr,                    // leave as nullptr if hardware is used
                creationFlags,              // optionally set debug and Direct2D compatibility flags
                featureLevels,
                ARRAYSIZE(featureLevels),
                D3D11_SDK_VERSION,          // always set this to D3D11_SDK_VERSION
                d3dDevice.put(),
                nullptr,
                d3dDeviceContext.put()
            )
        );

        // Retrieve the Direct3D 11.1 interfaces.
        m_d3dDevice = d3dDevice.as<ID3D11Device1>();
        m_d3dDeviceContext = d3dDeviceContext.as<ID3D11DeviceContext1>();

        // After the D3D device is created, create additional application resources.
        CreateWindowSizeDependentResources();

        // Enter the render loop.  Note that a UWP app should never exit.
        while (true)
        {
            // Process events incoming to the window.
            m_window.get().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);

            // Specify the render target we created as the output target.
            ID3D11RenderTargetView* const targets[1]{ m_renderTargetView.get() };
            m_d3dDeviceContext->OMSetRenderTargets(
                1,
                targets,
                nullptr // use no depth stencil
            );

            // Clear the render target to a solid color.
            const float clearColor[4] = { 0.071f, 0.04f, 0.561f, 1.0f };
            m_d3dDeviceContext->ClearRenderTargetView(
                m_renderTargetView.get(),
                clearColor
            );

            // Present the rendered image to the window.  Because the maximum frame latency is set to 1,
            // the render loop will generally be throttled to the screen refresh rate, typically around
            // 60Hz, by sleeping the application on Present until the screen is refreshed.
            winrt::check_hresult(
                m_swapChain->Present(1, 0)
            );
        }
    }
    void SetWindow(CoreWindow const& window)
    {
        m_window = window;

        // Specify the cursor type as the standard arrow cursor.
        m_window.get().PointerCursor(CoreCursor{ CoreCursorType::Arrow, 0 });

        // Allow the application to respond when the window size changes.
        window.SizeChanged({ this, &App::OnWindowSizeChanged });
    }
private:
    winrt::agile_ref<CoreWindow> m_window;
    winrt::com_ptr<IDXGISwapChain1> m_swapChain;
    winrt::com_ptr<ID3D11Device1> m_d3dDevice;
    winrt::com_ptr<ID3D11DeviceContext1> m_d3dDeviceContext;
    winrt::com_ptr<ID3D11RenderTargetView> m_renderTargetView;

かなり古い方法だとHRESULTのチェックも自前で行っていましたが、winrt::check_hresultでチェックできるようになったのは結構大きいですねぇと思いつつソースコードを見てました。

インターフェイス変換もasを挟むようになったのだなぁと進化したのだと…おいちゃんついていけるかわからへん。

そういえば、手打ちしている時に、「winrt::get_unknown」を書くのめんどくさくて「get_unknown」のみでしてましたがこれはダメっぽい、かぶっているのかそのまま使用できなかったのでしかたなく明示宣言。ここらへんはそのまま使用したかった。

…相変わらず Uninitialize 関数は呼ばれないんですよね。何か定義が足りないのか使用方法が間違っているのか。そのうちわかるだろうけどいったん放置。

【WinRT】いったん大本から勉強してみる

まずは、いったんブランクな状態にしてサンプルと見比べながら勉強してみる。

#include "pch.h"

using namespace winrt;

using namespace Windows;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    IFrameworkView CreateView()
    {
        return *this;
    }

    void Initialize(CoreApplicationView const &)
    {
    }

    void Load(hstring const&)
    {
    }

    void Uninitialize()
    {
    }

    void Run()
    {
        CoreWindow window = CoreWindow::GetForCurrentThread();
        window.Activate();

        CoreDispatcher dispatcher = window.Dispatcher();
        dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
    }

    void SetWindow(CoreWindow const &)
    {
    }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(make<App>());
}

プロジェクトを作成して、要らないコードを取っ払ってみた。かなりスッキリしているけどこれだけでWindowが出てくるから中々に便利だ。
CoreApplication::Runにインターフェイス盛り込んだstructureを登録してそれをスレッドで回しているってイメージかな。
WinAPIをいじっていた身からするとかなりの進歩具合、一気にワープした感じすらあるが…まぁそれはおいといて。

ざっくりとした認識は、CoreApplication 現?アプリケーションにアクセスするためのモノ、CoreWindow::GetForCurrentThread(); 現スレッドのウィンドウを取得する。

ひとまず起動、終了してみた感じでは以下の順で動いていた。

  1. CreateView
    • エントリーポイントで作成されたときに来る、登録するために現在のポインタを返す必要がある。
  2. Initialize
    • アプリビューの初期化。アプリオブジェクトの起動時に呼び出される。
  3. SetWindow
    • アプリオブジェクトの現在のビュー設定を行う個所、ウィンドウイベントなどの登録をここで行う
  4. Load
    • Runが呼び出される前のアプリケーションで使用する固定リソースなどの読み込みに使用する
  5. Run
    • 実行処理
  6. Uninitialize
    • いろいろいじったけど来なかった、終了するタイミングで来ると思うんだけどなんかわからんので放置

次は、サンプルを見つつ次の作業を決めていこう。
ダイレクトXを適当にいじいじしてみよう。

はじめてのWinRT

プログラマーを職にしてからかなり立ったが、知識が古いままなので更新しようと思いWinRT(Windowsランタイム)に手を出してみようと決意。

まずは、WinRTを導入するためにMSDNサイトを漁りつつVisualStudioの設定を行う。

  • Visual Studio 2019 Community のインストール
  • ユニバーサル開発の設定でインストール
  • 最新のWindowsSDKをインストール:この時のターゲットプラットフォームバージョンは[10.0.18362.0]
  • 個別コンポネントのタブでWinRTを入れる

ここまで導入してようやくWinRTのテスト用プロジェクトを作成できるようになった。けっこう入れなきゃいけないものが多くなったのですな。

テスト用プロジェクトを作成して、Nugetパッケージ管理からWinRTのパッケージ入れろっていわれたので導入して起動。

作成した直後の奴

プロジェクトを作成した段階ですでにサンプル的なものが入力されており、起動するとウィンドウが作成された。まぁ作っただけなのでまだ中身をみてないんだが…中身をみて思った事が一つ。「よし、何をしているか分からん!」状態だった。

見たところエントリーポイントの所はかなり簡略化されていて、WindowsAPIで使用していたHINSTANCE系のものはまるっと使用していないみたいだった。まぁ、WindowsAPIを使っている所って古代みたいな感じなんだろうか。

気を取り直してエントリポイントから見てみる。

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(make<App>());
}

CoreApplicationに作成したAPPを渡してるだけなので中で何かスレッド処理をしているんだろうなと…さてAPPのほうはというと

struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    ……

implementsが何をしているかさっぱりだけど、各種インターフェイスを継承しているってことくらいなのと…クラスではなくなった感じなんですの。まぁstructはclassとそう大差ないけど扱いやすいからの…structとclassはどっちが先だったか…まぁそこらへんはおいといて何か目標をたてるか。

  • 画像のロード
  • 画像表示

いったんここらへんにして次回へ…。

【PHP】ZipArchive に画像を直接書き込んでみる

この項目ではZipArchiveにメモリ情報から直接ファイルを登録してみようというものになります。
ZipArchiveの使用方法はあっても直接画像情報を登録することが出来なかったのでいろいろ試行錯誤しながらやっていたのでメモ程度に残していきます。


1.先ずは画像の文字列情報を作成する

ob_start();
imagepng($resource);
$buffer = ob_get_contents();
ob_end_clean();

これで一先ず画像の文字列情報が取得できます。
$resource にはGDを使用して作成したイメージデータが入っています。GDの使用の仕方については本家PHPのサイトを参照してください。

2.ZipArchiveに画像データを登録する

だいたいのZipArchiveの使用方法は addFile だったりの使用方法でしたが、この項では addFromString を使用して先ほど作成した画像の文字列データを登録していきます。

$zip = new ZipArchive();
$zip->open('test.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFromString($i . '.png', $buffer);
$zip->close();

これだけで特別ファイル出力を挟まないで、Zip作成だけを行う事が出来ます。
この手法がのっている場所が見当たらなかったので個人的に記述


知識的な噛み砕き

imagepng などGD関数で画像を作成するとフォーマットもろもろを含んだリソース情報を作成してくれます。
このリソース情報はいわゆる fopen などでファイルを開いてバッファに読み取ったような感じを想像できるかと思います。
なので、コレを文字列情報として取得して拡張子つけて保存すれば簡単に作成できたというわけですね。(ZipArchiveの中でどんな処理してるかは分かりませんが)

ひとまずメモ程度にここまで

PHPのシステム考えたい


【PHPの重い処理に関して】

PHPの重い処理の対策を検索してみる。

PHPの設定で「set_time_limit」を使用してタイムアウトを引き伸ばす。

良くある手法でset_time_limit(0);に設定することで処理を止めないようにする事が出来ますがコレはコレでHTTP側でのタイムアウトに阻まれてしまう可能性があるのでいい手法ともいえないかも。
処理中ページを移動できないのはユーザーに対してストレスにしかならない。

PHPの処理で「exec」を使用して処理事態を別プロセスとしてバックグラウンドで作業させる。

思った原因を解決しようとすると割りとこれが一番しっくり来る解決策。
ただ、やったことが無いので実装してみようかと思うと割りとかかりそう。

ApacheサーバーのRewriteMapについて

ApacheサーバーでのCache Busting

Cache Bustingを行う為に考えた事

  • 出来ればアドレスを換えずにCache Bustingを行いたい
  • Cache Bustingはファイルの更新日を使用する事で特定のファイルのキャッシュだけを削除させたい

出来ればアドレスを換えずにCache Bustingを行いたい

.htaccess のmod_rewriteを使用してみる

先ず結果だけを先にいうと「mod_rewrite の RewriteMap は .htaccess では使用することが出来ません!」という結果があります、Apacheの仕様なので仕方が無いです。

.htaccess はApacheの標準機能ですが、その中でmod_rewriteのモジュール機能を利用して特定のアドレスにアクセスがあった場合それを書き換えるという処理があり、その中にRewriteMapというものがあり、外部からphpなどプログラムを読み込んでアドレスを変更できるなどがあったので意気揚々と、記述したりいろいろ見てみたりして気づきました。

「mod_rewrite の RewriteMap は .htaccess では使用することが出来ません!」

マジかよと思いApache本家のContext部分を確認すると確かに .htaccess は存在しませんでした。なのでRewriteMapを記述する場合は httpd.conf などサーバー設定のファイルに直接記載するしかないようです……なんてこったいでしょう。

じゃあ httpd.conf に記載する?と考えると他のサーバーに移した時、特に httpd.conf などが触れないサーバーだったりすると詰んでしまうので却下…むしろ環境固有のモノになって他の環境で使用したいと考えた時に簡単に使用できないという事になってしまうので諦めました。

素直にアドレスにタグを埋め込む事にします。

Cache Bustingはファイルの更新日を使用する事で特定のファイルのキャッシュだけを削除させたい

URLの末尾にファイルの日付を入れる

Cache Bustingというのは他のページでもありますが簡潔に書くと「URLが変わったので新しくキャッシュを読み込みにいくよ!」という内容です。HTTPの仕様で参照しているURLが々であればキャッシュを行うというものです。

なのでURLを作る場合は「URL?date=ファイルの日付」などのほうが良いでしょう。そのままサーバーの日付にしてしまうと毎回新しいファイルとして読みにいってしまい重くなってしまいます。

ホームページのタグで描くとしたら以下の内容のようなものでしょうか。

<img src=”sample.png?date=20170530″>

一例ですが上記の場合20170530部分が書き換えられると新しいものと捉えて新しく取得しにいきます。ただコレだと自動的に作成されないので毎回書き直す必要があります。

もし環境が php などを使用している環境であれば、phpを使用してもいいでしょう。

function getFileURL($file_path)
{
    return $file_path . "?date=" . date("YmdHis", filemtime($file_path));
}

簡単に書くとこんな感じでしょうか。投げたファイルパスからファイルの更新日時を取得してdateで日付の文字列に変換して、ファイルパスに日付の文字列を付加して返却するというものです。あとはコレをphpのファイル側に入れればいいかんじかなと。

<img src=<?php echo ‘”‘ . getFileURL(“sample.png”) . ‘”‘; ?> >

…例としてこれでよかったっけ?と割りと雑ですがこんな感じできっと動くでしょうと…深夜に記事を書いているためか眠くて検証するまでにいたりませんでしたが一旦コレでストップ。

 

最後に

何かまたメモしたいものが増えたら徐々にふやしていこうかと考えてます。

電子書籍発売に向けての第一歩

苦節30年、生きてきたわけですがそろそろ本的なものを作ってみようかと思い立ち電子書籍なるものを調べているわけですが…いろいろありますね。

Googleで「電子書籍 出版」と検索するだけでも色々なサイトが引っかかります。その中で目立ったのはAmazoneのダイレクトパブリッシングというものでした。Amazoneさんはよく利用させてもらっているのと、大きい会社という事で安心して利用できるかなと思いここでやってみようかと。

しかし、文章を書くことが苦手な自分としては電子書籍…しかも文章だけのものを作ることができるのだろうかと不安になりました。何故なら気をつけていないと「~でした。」やら「~です。」などの文章が連続で続いてしまうからです。文章であらわすので仕方ない部分もあったりはするのですが・・・。

というか、一番最初の投稿でもう少し砕けた感じで書くというのが既にできてなくて笑ってしまう。

さて、先ずは文章のフォーマット。

Amazone : ファイル形式に関するヒント

ここのページでは、電子書籍の作成についてのフォーマットがずらっと並んでいます。Wordを持っているのであればそちらを利用したほうが便利ですと書かれているのでそちらを利用…できそうにない…エクセルはあっても自分はWordをもっていないのだった。

…他にも手法はあるようだが、Wordが便利ならそちらを使いたいところなのだが…で…結局調べてる最中にわかったのだが「HTMLに最終的に変換してZIPに圧縮してアップロードする」ということだった。

テキストファイルで実際に作ってみるのがはやそうですな。

Amazone : Kindle パブリッシング・ガイドライン

ガイドラインがありました。今日のところは手をつけるのが遅かったのでもう少し調べながら何がいいか試行錯誤する必要があるなと…。

 

実際に出せるのになるのにどれ位かかるだろうかなぁ…

WordPressでブログ表示をトップに持ってくる

よくあるブログ表示についてですが、いろいろなサイトを回ってみて結局PHPいじれや!みたいな事がかいてあったり、固定ページを用意して云々とちょっとげんなりしてましたが、ふと設定の表示一覧を見ていてコレじゃね?というのがあったので試したら一発でいけました。

そうだよ、ブログのように投稿した奴がトップページに表示されたいんですよ。

で、何をしたかというと「表示設定のフロントページの表示」を最新の投稿にチェックを入れただけですね。まさかコレだけで、最新のブログ投稿が表示されるようになったなんて…。最近は便利になりましたね。

WordPress設定

日記用サイトを構築

日記サイト以外にも個人的に運用しているサイトがあるけれど、こちらは日記形式で書いていこうかと…。文章を書いているうちにだんだんと丁寧な言葉になってしまうので、日記ではできるだけ崩してかこうかななんて…。

今日は面接日、ゲーム会社への面接に行きます。ゲームプログラマーを始めて10年近くになりますが、相変わらず底辺プログラマーではいつくばっている感じでお金は欲しいが休みも欲しい。ここら辺は他の人と同じですね(´・ω・`)

こんな感じでドンドンと今後の活動についても描いていこうかと思います。