Skip to content
Permalink
Browse files

Merge pull request #1511 from TheCycoONE/cpp14

[RDY] Modernizing C++
  • Loading branch information...
Alberth289346 committed May 28, 2019
2 parents d655142 + f4e6ee0 commit 4ba54f2c971a7fcd23b9d688f66165f2d232280f
@@ -46,7 +46,7 @@ else()
endif()

# Set language standard
set_property(TARGET AnimView PROPERTY CXX_STANDARD 11)
set_property(TARGET AnimView PROPERTY CXX_STANDARD 14)
set_property(TARGET AnimView PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET AnimView PROPERTY CXX_STANDARD_REQUIRED ON)

@@ -79,7 +79,7 @@ if(UNIX AND NOT APPLE)
endif()

# Set language standard
set_property(TARGET CorsixTH PROPERTY CXX_STANDARD 11)
set_property(TARGET CorsixTH PROPERTY CXX_STANDARD 14)
set_property(TARGET CorsixTH PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET CorsixTH PROPERTY CXX_STANDARD_REQUIRED ON)

@@ -23,7 +23,7 @@ SOFTWARE.
#include "th_lua.h"
#include "config.h"
#include <cstring>
#include <vector>
#include <array>

/* Often, an error occurs during the CorsixTH startup process. Examples of
such errors include:
@@ -40,8 +40,10 @@ font data and Lua script are hardcoded into this file (the font itself is a
homemade bitmap font, as we cannot rely on TH fonts being present).
*/

static const int first_bootstrap_code_line_number = __LINE__ + 2;
static const char* bootstrap_code[] = {
namespace {

constexpr int first_bootstrap_code_line_number = __LINE__ + 2;
constexpr std::array<const char*, 45> bootstrap_code {{
"local lines, dat, tab, pal, err = {}, ...",
"local function t(s) return s:gsub('\\t', ' ') end",
"for s in tostring(err):gmatch'[^\\r\\n]+' do lines[#lines+1] = t(s) end",
@@ -87,11 +89,11 @@ static const char* bootstrap_code[] = {
" if running then print(e) end",
"until where ~= 'callback'",
nullptr
};
}};

/* Start autogenerated content */
/* Data from bootstrap_font.tab inserted by mkbootstrap.lua: */
static const std::vector<uint8_t> bootstrap_font_tab = {
constexpr std::array<uint8_t, 499> bootstrap_font_tab {
0x52, 0x4E, 0x43, 0x01, 0x00, 0x00, 0x05, 0x46, 0x00, 0x00, 0x01, 0xE1, 0xFB,
0xF2, 0x66, 0x51, 0xBE, 0xEF, 0x0C, 0x09, 0x59, 0x60, 0x10, 0x34, 0x43, 0x54,
0xA6, 0x46, 0xA2, 0x08, 0x00, 0xA0, 0xC4, 0x01, 0xF6, 0x3D, 0x00, 0x00, 0xAF,
@@ -132,8 +134,9 @@ static const std::vector<uint8_t> bootstrap_font_tab = {
0xA8, 0xCF, 0xF2, 0x75, 0x53, 0x0D, 0x13, 0xFA, 0x24, 0x1E, 0x51, 0xB9, 0xC9,
0x29, 0x40, 0x52, 0x7D, 0x0F
};

/* Data from bootstrap_font.dat inserted by mkbootstrap.lua: */
static const std::vector<uint8_t> bootstrap_font_dat = {
constexpr std::array<uint8_t, 1534> bootstrap_font_dat {
0x52, 0x4E, 0x43, 0x01, 0x00, 0x00, 0x13, 0x68, 0x00, 0x00, 0x05, 0xEC, 0xD3,
0x6C, 0x7E, 0xAB, 0xBE, 0xEF, 0x94, 0x90, 0x81, 0x61, 0x50, 0x34, 0x44, 0x33,
0x33, 0x53, 0x66, 0x64, 0x64, 0x26, 0x20, 0x60, 0x47, 0x1E, 0x01, 0xFF, 0x84,
@@ -254,7 +257,7 @@ static const std::vector<uint8_t> bootstrap_font_dat = {
0x02, 0xAC, 0x9A, 0x43, 0x10, 0xB5, 0x0A, 0xA0, 0x17, 0x1C, 0xA6, 0x00, 0x9B
};
/* Data from bootstrap_font.pal inserted by mkbootstrap.lua: */
static const std::vector<uint8_t> bootstrap_font_pal = {
constexpr std::array<uint8_t, 47> bootstrap_font_pal {
0x52, 0x4E, 0x43, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB7,
0xFF, 0x76, 0x79, 0xBE, 0xEF, 0x90, 0x10, 0x90, 0x05, 0x01, 0x02, 0x00, 0x00,
0x20, 0x2B, 0x04, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0xB6, 0x00, 0x00, 0x00,
@@ -263,7 +266,7 @@ static const std::vector<uint8_t> bootstrap_font_pal = {
/* End autogenerated content */

// Lua reader function for loading bootstrap_code
static const char* read_bootstrap_line(lua_State *L, void *data, size_t *size)
const char* read_bootstrap_line(lua_State *L, void *data, size_t *size)
{
int& iLine = *reinterpret_cast<int*>(data);
++iLine;
@@ -288,11 +291,14 @@ static const char* read_bootstrap_line(lua_State *L, void *data, size_t *size)
}
}

static inline void push(lua_State *L, std::vector<uint8_t> data)
template<typename Array>
inline void push(lua_State *L, Array data)
{
lua_pushlstring(L, reinterpret_cast<const char*>(data.data()), data.size());
}

} // namespace

int bootstrap_lua_resources(lua_State *L)
{
push(L, bootstrap_font_dat);
@@ -1,4 +1,9 @@
static const uint16_t cp437_to_unicode_table[0x80] = {
#ifndef CORSIX_TH_CP437_TO_UNICODE_TABLE_H
#define CORSIX_TH_CP437_TO_UNICODE_TABLE_H

#include <array>

constexpr std::array<uint16_t, 0x80> cp437_to_unicode_table {
/* 0x00 through 0x7F need no translation */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
@@ -17,3 +22,5 @@ static const uint16_t cp437_to_unicode_table[0x80] = {
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};

#endif
@@ -1,10 +1,14 @@
#ifndef CORSIX_TH_CP936_TO_UNICODE_TABLE_H
#define CORSIX_TH_CP936_TO_UNICODE_TABLE_H

#include <array>
// Generated from the following document:
// http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT
// Maps double-byte characters where:
// 1st byte is between 0x81 and 0xFE (subtract 0x81 for table lookup)
// 2nd byte is between 0x40 and 0xFE (subtract 0x40 for table lookup)
// Unspecified codes are mapped to 0x003F
static const uint16_t cp936_to_unicode_table[126][191] = {
constexpr std::array<std::array<uint16_t, 191>, 126> cp936_to_unicode_table {{
{
0x4E02, 0x4E04, 0x4E05, 0x4E06, 0x4E0F, 0x4E12, 0x4E17, 0x4E1F,
0x4E20, 0x4E21, 0x4E23, 0x4E26, 0x4E29, 0x4E2E, 0x4E2F, 0x4E31,
@@ -3281,4 +3285,6 @@ static const uint16_t cp936_to_unicode_table[126][191] = {
0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F,
0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F, 0x003F
}
};
}};

#endif
@@ -26,6 +26,66 @@ SOFTWARE.
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <array>

namespace {

enum iso_volume_descriptor_type : uint8_t
{
vdt_privary_volume = 0x01,
// Other type numbers are either reserved for future use, or are not
// interesting to us.
vdt_terminator = 0xFF,
};

enum iso_dir_ent_flag : uint8_t
{
def_hidden = 0x01,
def_directory = 0x02,
def_multi_extent = 0x80,
};

/// Offset to the 32bit sector of the file data
/// from the start of the file entry.
constexpr ptrdiff_t file_sector_offset = 2;

/// Offset to the 32bit length of the file data
/// from the start of the file entry
constexpr ptrdiff_t file_data_length_offset = 10;

/// The offset of the file flags (e.g. directory vs file)
/// from the start of the file entry.
constexpr ptrdiff_t file_flags_offset = 25;

/// The offset of the byte that stores the length of the filename
/// from the start of the file entry.
constexpr ptrdiff_t filename_length_offset = 32;

/// The offset of the start of the filename or directory identifier
/// from the start of the file entry.
constexpr ptrdiff_t filename_offset = 33;

/// Formal depth limit in spec is 8. We allows for loose implementations.
constexpr int max_directory_depth = 16;

/// Reasonably unique name of a file from Theme Hospital that can be used to
/// indicate that we've loaded the right directory.
constexpr std::array<const char, 10> vblk_0_filename {'V','B','L','K','-','0','.','T','A','B'};

/// Sector sizes can vary, but they must be powers of two, and the minimum
/// size is 2048.
constexpr size_t min_sector_size = 2048;

template <class T> inline T read_native_int(const uint8_t *p)
{
// ISO 9660 commonly encodes multi-byte integers as little endian followed
// by big endian. Note that the first byte of iEndianness will be a zero on
// little endian systems, and a one on big endian.
static const uint16_t iEndianness = 0x0100;
return reinterpret_cast<const T*>(p)[*reinterpret_cast<const uint8_t*>(&iEndianness)];
}

} // namespace

iso_filesystem::iso_filesystem()
{
@@ -63,37 +123,13 @@ void iso_filesystem::set_path_separator(char cSeparator)
path_seperator = cSeparator;
}

enum iso_volume_descriptor_type : uint8_t
{
vdt_privary_volume = 0x01,
// Other type numbers are either reserved for future use, or are not
// interesting to us.
vdt_terminator = 0xFF,
};

enum iso_dir_ent_flag : uint8_t
{
def_hidden = 0x01,
def_directory = 0x02,
def_multi_extent = 0x80,
};

template <class T> static inline T read_native_int(const uint8_t *p)
{
// ISO 9660 commonly encodes multi-byte integers as little endian followed
// by big endian. Note that the first byte of iEndianness will be a zero on
// little endian systems, and a one on big endian.
static const uint16_t iEndianness = 0x0100;
return reinterpret_cast<const T*>(p)[*reinterpret_cast<const uint8_t*>(&iEndianness)];
}

bool iso_filesystem::initialise(FILE* fRawFile)
{
raw_file = fRawFile;
clear();

// Until we know better, assume that sectors are 2048 bytes.
sector_size = 2048;
sector_size = min_sector_size;

// The first 16 sectors are reserved for bootable media.
// Volume descriptor records follow this, with one record per sector.
@@ -162,7 +198,7 @@ int iso_filesystem::find_hosp_directory(const uint8_t *pDirEnt, int iDirEntsSize
// Apart from at the root level, directory record arrays must take up whole
// sectors, whose sizes are powers of two and at least 2048.
// The formal limit on directory depth is 8, so hitting 16 is insane.
if((iLevel != 0 && (iDirEntsSize & 0x7FF)) || iLevel > 16)
if((iLevel != 0 && (iDirEntsSize & (min_sector_size - 1)) != 0) || iLevel > max_directory_depth)
return 0;

uint8_t *pBuffer = nullptr;
@@ -176,17 +212,17 @@ int iso_filesystem::find_hosp_directory(const uint8_t *pDirEnt, int iDirEntsSize
continue;
}

uint32_t iDataSector = read_native_int<uint32_t>(pDirEnt + 2);
uint32_t iDataLength = read_native_int<uint32_t>(pDirEnt + 10);
uint8_t iFlags = pDirEnt[25];
uint8_t iIdentLength = pDirEnt[32];
trim_identifier_version(pDirEnt + 33, iIdentLength);
uint32_t iDataSector = read_native_int<uint32_t>(pDirEnt + file_sector_offset);
uint32_t iDataLength = read_native_int<uint32_t>(pDirEnt + file_data_length_offset);
uint8_t iFlags = pDirEnt[file_flags_offset];
uint8_t iIdentLength = pDirEnt[filename_length_offset];
trim_identifier_version(pDirEnt + filename_offset, iIdentLength);
if(iFlags & def_directory)
{
// The names "\x00" and "\x01" are used for the current directory
// the parent directory respectively. We only want to visit these
// when at the root level.
if(iLevel == 0 || iIdentLength != 1 || pDirEnt[33] > 1)
if(iLevel == 0 || iIdentLength != 1 || pDirEnt[filename_offset] > 1)
{
if(iDataLength > iBufferSize)
{
@@ -211,16 +247,15 @@ int iso_filesystem::find_hosp_directory(const uint8_t *pDirEnt, int iDirEntsSize
{
// Look for VBLK-0.TAB to serve as indication that we've found the
// Theme Hospital data.
if(iIdentLength == 10)
if(iIdentLength == vblk_0_filename.size())
{
const char sName[10] = {'V','B','L','K','-','0','.','T','A','B'};
int i = 0;
for(; i < 10; ++i)
for(; i < vblk_0_filename.size(); ++i)
{
if(normalise(pDirEnt[33 + i]) != sName[i])
if(normalise(pDirEnt[filename_offset + i]) != vblk_0_filename.at(i))
break;
}
if(i == 10)
if(i == vblk_0_filename.size())
{
return 1;
}
@@ -259,19 +294,19 @@ void iso_filesystem::build_file_lookup_table(uint32_t iSector, int iDirEntsSize,
continue;
}

uint32_t iDataSector = read_native_int<uint32_t>(pDirEnt + 2);
uint32_t iDataLength = read_native_int<uint32_t>(pDirEnt + 10);
uint8_t iFlags = pDirEnt[25];
uint8_t iIdentLength = pDirEnt[32];
trim_identifier_version(pDirEnt + 33, iIdentLength);
uint32_t iDataSector = read_native_int<uint32_t>(pDirEnt + file_sector_offset);
uint32_t iDataLength = read_native_int<uint32_t>(pDirEnt + file_data_length_offset);
uint8_t iFlags = pDirEnt[file_flags_offset];
uint8_t iIdentLength = pDirEnt[filename_length_offset];
trim_identifier_version(pDirEnt + filename_offset, iIdentLength);

// Build new path
char *sPath = new char[iLen + iIdentLength + 2];
std::memcpy(sPath, sPrefix, iLen);
#ifdef _MSC_VER
#pragma warning(disable: 4996)
#endif
std::transform(pDirEnt + 33, pDirEnt + 33 + iIdentLength, sPath + iLen, normalise);
std::transform(pDirEnt + filename_offset, pDirEnt + filename_offset + iIdentLength, sPath + iLen, normalise);
#ifdef _MSC_VER
#pragma warning(default: 4996)
#endif
@@ -448,21 +483,23 @@ void iso_filesystem::set_error(const char* sFormat, ...)
va_end(a);
}

static int l_isofs_new(lua_State *L)
namespace {

int l_isofs_new(lua_State *L)
{
luaT_stdnew<iso_filesystem>(L, luaT_environindex, true);
return 1;
}

static int l_isofs_set_path_separator(lua_State *L)
int l_isofs_set_path_separator(lua_State *L)
{
iso_filesystem *pSelf = luaT_testuserdata<iso_filesystem>(L);
pSelf->set_path_separator(luaL_checkstring(L, 2)[0]);
lua_settop(L, 1);
return 1;
}

static int l_isofs_set_root(lua_State *L)
int l_isofs_set_root(lua_State *L)
{
iso_filesystem *pSelf = luaT_testuserdata<iso_filesystem>(L);
FILE *fIso = *luaT_testuserdata<FILE*>(L, 2);
@@ -481,7 +518,7 @@ static int l_isofs_set_root(lua_State *L)
}
}

static int l_isofs_read_contents(lua_State *L)
int l_isofs_read_contents(lua_State *L)
{
iso_filesystem *pSelf = luaT_testuserdata<iso_filesystem>(L);
const char* sFilename = luaL_checkstring(L, 2);
@@ -503,15 +540,15 @@ static int l_isofs_read_contents(lua_State *L)
return 1;
}

static void l_isofs_list_files_callback(void *p, const char* s)
void l_isofs_list_files_callback(void *p, const char* s)
{
lua_State *L = reinterpret_cast<lua_State*>(p);
lua_pushstring(L, s);
lua_pushboolean(L, 1);
lua_settable(L, 3);
}

static int l_isofs_list_files(lua_State *L)
int l_isofs_list_files(lua_State *L)
{
iso_filesystem *pSelf = luaT_testuserdata<iso_filesystem>(L);
const char* sPath = luaL_checkstring(L, 2);
@@ -521,6 +558,8 @@ static int l_isofs_list_files(lua_State *L)
return 1;
}

} // namespace

int luaopen_iso_fs(lua_State *L)
{
lua_settop(L, 1);

0 comments on commit 4ba54f2

Please sign in to comment.
You can’t perform that action at this time.