Init dchip-8 repo with bare bones win32 app

This commit is contained in:
Doyle Thai 2017-03-28 18:40:38 +11:00
parent 4d52fb6eaa
commit 076f5977a3
8 changed files with 397 additions and 1 deletions

7
.gitignore vendored
View File

@ -1,3 +1,10 @@
################################################################################
# MANUAL ENTRIES
################################################################################
tags
*.swp
*.swo
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

View File

@ -68,13 +68,22 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)\bin\</OutDir>
<IntDir>$(SolutionDir)\bin\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -110,6 +119,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\dchip-8.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -14,4 +14,9 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\dchip-8.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

46
src/.clang-format Normal file
View File

@ -0,0 +1,46 @@
{
ColumnLimit: 80,
TabWidth: 4,
IndentWidth: 4, # 1 tab
UseTab: ForIndentation,
BreakBeforeBraces: Allman,
PointerBindsToType: false,
###
AlwaysBreakAfterDefinitionReturnType: false,
AlwaysBreakTemplateDeclarations: true,
AlwaysBreakBeforeMultilineStrings: true,
IndentFunctionDeclarationAfterType: false,
#
AccessModifierOffset: -4, # 1 tab
AlignAfterOpenBracket: true,
AlignConsecutiveAssignments: true,
AlignTrailingComments: true,
#
AllowAllParametersOfDeclarationOnNextLine: true,
AllowShortBlocksOnASingleLine: false,
AllowShortIfStatementsOnASingleLine: true,
AllowShortLoopsOnASingleLine: false,
#
BinPackArguments: true,
BinPackParameters: true,
#
BreakConstructorInitializersBeforeComma: true,
ConstructorInitializerIndentWidth: 0,
#
IndentCaseLabels: true,
#
MaxEmptyLinesToKeep: 1,
NamespaceIndentation: None,
#
SpaceBeforeAssignmentOperators: true,
SpaceInEmptyParentheses: false,
SpacesBeforeTrailingComments: 1,
SpacesInAngles: false,
SpacesInCStyleCastParentheses: false,
SpacesInParentheses: false,
SpacesInSquareBrackets: false,
#
Cpp11BracedListStyle: true,
Standard: Cpp11,
#
}

128
src/Common.h Normal file
View File

@ -0,0 +1,128 @@
#ifndef COMMON_H
#define COMMON_H
#include "stdint.h"
#define LOCAL_PERSIST static
#define GLOBAL_VAR static
#define FILE_SCOPE static
typedef uint32_t u32;
typedef uint16_t u16;
typedef int64_t i64;
typedef int32_t i32;
typedef int16_t i16;
typedef float f32;
typedef unsigned char u8;
#define INVALID_CODE_PATH 0
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
#ifdef DEBUG_MODE
#define ASSERT(expr) if (!(expr)) { (*((int *)0)) = 0; }
#else
#define ASSERT(expr)
#endif
#define MATH_ABS(x) (((x) < 0) ? (-(x)) : (x))
typedef union v2 {
struct { f32 x, y; };
struct { f32 w, h; };
} v2;
inline FILE_SCOPE v2 V2(f32 x, f32 y)
{
v2 result = {};
result.x = x;
result.y = y;
return result;
}
inline FILE_SCOPE v2 V2i(i32 x, i32 y)
{
v2 result = V2((f32)x, (f32)y);
return result;
}
inline FILE_SCOPE i32 common_strcmp(const char *a, const char *b)
{
while ((*a) == (*b))
{
if (!(*a)) return 0;
a++;
b++;
}
return (((*a) < (*b)) ? -1 : 1);
}
inline FILE_SCOPE i32 common_wstrcmp(const wchar_t *a, const wchar_t *b)
{
while ((*a) == (*b))
{
if (!(*a)) return 0;
a++;
b++;
}
return (((*a) < (*b)) ? -1 : 1);
}
inline FILE_SCOPE void common_wstrcat(const wchar_t *a, i32 lenA,
const wchar_t *b, i32 lenB, wchar_t *out,
i32 outLen)
{
ASSERT((lenA + lenB) < outLen);
i32 outIndex = 0;
for (i32 i = 0; i < lenA; i++)
out[outIndex++] = a[i];
for (i32 i = 0; i < lenB; i++)
out[outIndex++] = b[i];
ASSERT(outIndex <= outLen);
}
inline FILE_SCOPE wchar_t common_wcharAsciiToLowercase(wchar_t character)
{
if (character >= L'A' && character <= L'Z')
{
i32 shiftOffset = L'a' - L'A';
character += (wchar_t)shiftOffset;
}
return character;
}
inline FILE_SCOPE i32 common_wstrlen(const wchar_t *a)
{
i32 result = 0;
while ((*a))
{
result++;
a++;
}
return result;
}
inline FILE_SCOPE i32 common_strlen(const char *a)
{
i32 result = 0;
while ((*a))
{
result++;
a++;
}
return result;
}
#endif

54
src/build.bat Normal file
View File

@ -0,0 +1,54 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or
@REM vcvarsall.bat to setup command-line compiler.
@echo OFF
set ProjectName=dchip-8
ctime -begin %ProjectName%.ctm
REM Build tags file
ctags -R
REM Check if build tool is on path
REM >nul, 2>nul will remove the output text from the where command
where cl.exe >nul 2>nul
if %errorlevel%==1 call msvc86.bat
REM Drop compilation files into build folder
IF NOT EXIST ..\bin mkdir ..\bin
pushd ..\bin
REM EHa- disable exception handling (we don't use)
REM GR- disable c runtime type information (we don't use)
REM MD use dynamic runtime library
REM MT use static runtime library, so build and link it into exe
REM Oi enable intrinsics optimisation, let us use CPU intrinsics if there is one
REM instead of generating a call to external library (i.e. CRT).
REM Zi enables debug data, Z7 combines the debug files into one.
REM W4 warning level 4
REM WX treat warnings as errors
REM wd4100 ignore: unused argument parameters
REM wd4201 ignore: nonstandard extension used: nameless struct/union
REM wd4189 ignore: local variable is initialised but not referenced
set CompileFlags=-EHa- -GR- -Oi -MT -Z7 -W4 -WX -wd4100 -wd4201 -wd4189
REM Include directories
set IncludeFlags=
REM Link libraries
set LinkLibraries=user32.lib gdi32.lib
REM incrmenetal:no, turn incremental builds off
REM opt:ref, try to remove functions from libs that are referenced at all
set LinkFlags=-incremental:no -opt:ref
cl %CompileFlags% ..\src\%ProjectName%.cpp %IncludeFlags% /link -subsystem:WINDOWS,5.1 %LinkLibraries% %LinkFlags% /nologo /OUT:"%ProjectName%.exe"
popd
ctime -end %ProjectName%.ctm

BIN
src/ctime.exe Normal file

Binary file not shown.

146
src/dchip-8.cpp Normal file
View File

@ -0,0 +1,146 @@
#define UNICODE
#define _UNICODE
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "Common.h"
#include <Windows.h>
#include <stdio.h>
FILE_SCOPE bool globalRunning = false;
FILE_SCOPE LRESULT CALLBACK mainWindowProcCallback(HWND window, UINT msg,
WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
switch (msg)
{
case WM_CLOSE:
case WM_DESTROY:
{
globalRunning = false;
}
break;
default:
{
result = DefWindowProc(window, msg, wParam, lParam);
}
break;
}
return result;
}
GLOBAL_VAR LARGE_INTEGER globalQueryPerformanceFrequency;
inline FILE_SCOPE f32 getTimeFromQueryPerfCounter(LARGE_INTEGER start,
LARGE_INTEGER end)
{
f32 result = (f32)(end.QuadPart - start.QuadPart) /
globalQueryPerformanceFrequency.QuadPart;
return result;
}
inline FILE_SCOPE LARGE_INTEGER getWallClock()
{
LARGE_INTEGER result;
QueryPerformanceCounter(&result);
return result;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wc =
{
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW,
mainWindowProcCallback,
0, // int cbClsExtra
0, // int cbWndExtra
hInstance,
LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW),
GetSysColorBrush(COLOR_3DFACE),
L"", // LPCTSTR lpszMenuName
L"dchip-8Class",
NULL, // HICON hIconSm
};
if (!RegisterClassEx(&wc)) {
// TODO(doyle): Logging, couldn't register class
ASSERT(INVALID_CODE_PATH);
return -1;
}
// NOTE: Regarding Window Sizes
// If you specify a window size, e.g. 800x600, Windows regards the 800x600
// region to be inclusive of the toolbars and side borders. So in actuality,
// when you blit to the screen blackness, the area that is being blitted to
// is slightly smaller than 800x600. Windows provides a function to help
// calculate the size you'd need by accounting for the window style.
RECT r = {};
r.right = 450;
r.bottom = 200;
DWORD windowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
AdjustWindowRect(&r, windowStyle, FALSE);
globalRunning = true;
HWND mainWindow = CreateWindowEx(
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top,
nullptr, nullptr, hInstance, nullptr);
if (!mainWindow)
{
// TODO(doyle): Logging, couldn't create root window
ASSERT(INVALID_CODE_PATH);
return -1;
}
QueryPerformanceFrequency(&globalQueryPerformanceFrequency);
LARGE_INTEGER startFrameTime;
const f32 targetFramesPerSecond = 16.0f;
f32 targetSecondsPerFrame = 1 / targetFramesPerSecond;
f32 frameTimeInS = 0.0f;
MSG msg;
while (globalRunning)
{
startFrameTime = getWallClock();
while (PeekMessage(&msg, mainWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
LARGE_INTEGER endWorkTime = getWallClock();
f32 workTimeInS =
getTimeFromQueryPerfCounter(startFrameTime, endWorkTime);
if (workTimeInS < targetSecondsPerFrame)
{
DWORD remainingTimeInMs =
(DWORD)((targetSecondsPerFrame - workTimeInS) * 1000);
Sleep(remainingTimeInMs);
}
LARGE_INTEGER endFrameTime = getWallClock();
frameTimeInS =
getTimeFromQueryPerfCounter(startFrameTime, endFrameTime);
f32 msPerFrame = 1000.0f * frameTimeInS;
wchar_t windowTitleBuffer[128] = {};
_snwprintf_s(windowTitleBuffer, ARRAY_COUNT(windowTitleBuffer),
ARRAY_COUNT(windowTitleBuffer), L"dchip-8 | %5.2f ms/f",
msPerFrame);
SetWindowText(mainWindow, windowTitleBuffer);
}
return 0;
}