-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Boilerplate #1
base: master
Are you sure you want to change the base?
Boilerplate #1
Changes from all commits
4709f81
be7e079
4f2d0f3
e6d8063
751c970
29bf0a1
3815459
9ecea03
670cff0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdarg.h> | ||
#include <stddef.h> | ||
#include <assert.h> | ||
#include <ctype.h> | ||
|
||
#define _USE_MATH_DEFINES | ||
#include <math.h> | ||
|
||
typedef unsigned char byte; | ||
typedef unsigned char uint8; | ||
typedef signed char int8; | ||
typedef unsigned short uint16; | ||
typedef signed short int16; | ||
typedef unsigned int uint32; | ||
typedef signed int int32; | ||
typedef unsigned int uint; | ||
typedef signed long long int64; | ||
typedef unsigned long long uint64; | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include "emusys.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in general, try to use |
||
|
||
// Below macros are used for converting | ||
// Little Endian data to Big Endian and vice versa | ||
// This uses MSVC's and GCC's stdlib header | ||
// Using inline implmentations for other compilers | ||
#if defined(__GNUC__) | ||
#define SWAP_BYTES_64(a) __builtin_bswap64(a) | ||
#define SWAP_BYTES_32(a) __builtin_bswap32(a) | ||
#define SWAP_BYTES_16(a) __builtin_bswap16(a) | ||
#elif defined(_MSC_VER) | ||
#define SWAP_BYTES_64(a) _byteswap_uint64(a) | ||
#define SWAP_BYTES_32(a) _byteswap_ulong(a) | ||
#define SWAP_BYTES_16(a) _byteswap_ushort(a) | ||
#else | ||
inline uint64 SWAP_BYTES_64(uint64 a) { | ||
uint32 low = (uint32)a, high = (uint32)(a >> 32); | ||
uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16), highLow = (uint16)high, highHigh = (uint16)(high >> 16); | ||
|
||
return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) | (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) | (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) | (uint16)((highHigh >> 8) | (highHigh << 8))); | ||
} | ||
inline uint32 SWAP_BYTES_32(uint32 a) { | ||
const uint16 low = (uint16)a, high = (uint16)(a >> 16); | ||
return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16) | (uint16)((high >> 8) | (high << 8)); | ||
} | ||
inline uint16 SWAP_BYTES_16(const uint16 a) { | ||
return (a >> 8) | (a << 8); | ||
} | ||
#endif | ||
|
||
|
||
// We assume the machine to be Little Endian by default | ||
// As this is running on Intel, AMD and Apple Silicon chips | ||
// Will add compatibility for Big Endian machine later | ||
|
||
inline uint16 READ_UINT16(const void *ptr) { | ||
const uint8 *b = (const uint8 *)ptr; | ||
return (b[1] << 8) | b[0]; | ||
} | ||
Comment on lines
+36
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you're writing for little endian, why not do: inline uint16 READ_UINT16(const void *ptr) {
const uint16 *b = (const uint16 *)ptr;
return *b;
} you can even do this template<typename T>
static inline T READ(const void *ptr) {
const uint16 *b = (const uint16 *)ptr;
return *b;
}
// And if you don't want to use READ<uint32> everywhere:
static inline uint32 READ_UINT32(const void *ptr) {
return READ<uint32>(ptr);
}
... (try using static inline as much as you can) Also please avoid using Using constexprs you can even write a common definition for loading LE values on a BE and LE system: template<typename T>
constexpr static inline T READ(const void *ptr) {
// set isBigEnding somewhere using constexpers to detect
if constexpr (isBigEndian) {
constexpr size_t byteCount = sizeof(T);
T res = 0;
// This will be unrolled easily
for(size_t i = byteCount - 1; i >= 0; i-- ) {
res |= (((T*)ptr)[i] << (i * 8));
}
return res;
}
else {
const uint16 *b = (const uint16 *)ptr;
return *b;
}
} ^ This can very easily be extended to get support BE values on a BE and LE system as well with a couple of more if branches and is pretty idiomatic. |
||
|
||
inline uint32 READ_UINT32(const void *ptr) { | ||
const uint8 *b = (const uint8 *)ptr; | ||
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); | ||
} | ||
|
||
inline uint64 READ_UINT64(const void *ptr) { | ||
const uint8 *b = (const uint8 *)ptr; | ||
return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]); | ||
} | ||
|
||
inline void WRITE_UINT16(void *ptr, uint16 value) { | ||
uint8 *b = (uint8 *)ptr; | ||
b[0] = (uint8)(value >> 0); | ||
b[1] = (uint8)(value >> 8); | ||
} | ||
|
||
inline void WRITE_UINT32(void *ptr, uint32 value) { | ||
uint8 *b = (uint8 *)ptr; | ||
b[0] = (uint8)(value >> 0); | ||
b[1] = (uint8)(value >> 8); | ||
b[2] = (uint8)(value >> 16); | ||
b[3] = (uint8)(value >> 24); | ||
} | ||
|
||
inline void WRITE_UINT64(void *ptr, uint64 value) { | ||
uint8 *b = (uint8 *)ptr; | ||
b[0] = (uint8)(value >> 0); | ||
b[1] = (uint8)(value >> 8); | ||
b[2] = (uint8)(value >> 16); | ||
b[3] = (uint8)(value >> 24); | ||
b[4] = (uint8)(value >> 32); | ||
b[5] = (uint8)(value >> 40); | ||
b[6] = (uint8)(value >> 48); | ||
b[7] = (uint8)(value >> 56); | ||
} | ||
|
||
// Used in Common::Stream | ||
#define READ_LE_UINT16(a) READ_UINT16(a) | ||
#define READ_LE_UINT32(a) READ_UINT32(a) | ||
#define READ_LE_UINT64(a) READ_UINT64(a) | ||
#define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v) | ||
#define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v) | ||
#define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v) | ||
#define FROM_LE_16(a) ((uint16)(a)) | ||
#define FROM_LE_32(a) ((uint32)(a)) | ||
#define FROM_LE_64(a) ((uint64)(a)) | ||
#define FROM_BE_16(a) SWAP_BYTES_16(a) | ||
#define FROM_BE_32(a) SWAP_BYTES_32(a) | ||
#define FROM_BE_64(a) SWAP_BYTES_64(a) | ||
#define TO_LE_16(a) ((uint16)(a)) | ||
#define TO_LE_32(a) ((uint32)(a)) | ||
#define TO_LE_64(a) ((uint64)(a)) | ||
#define TO_BE_16(a) SWAP_BYTES_16(a) | ||
#define TO_BE_32(a) SWAP_BYTES_32(a) | ||
#define TO_BE_64(a) SWAP_BYTES_64(a) | ||
|
||
// Might come handy later | ||
#define LITTLE_ENDIAN false | ||
#define BIG_ENDIAN true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
//Taken from ScummVM's Common::Stream | ||
|
||
#include "endianness.h" | ||
|
||
namespace Common { | ||
class Stream { | ||
public: | ||
virtual ~Stream() {} | ||
|
||
// Below functions throw error and reset the error flag | ||
// Similar to ferror() and clearerr() | ||
|
||
virtual bool err() const { return false; } | ||
virtual void clearError() {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make this a purely virtual function |
||
}; | ||
|
||
class ReadStream : virtual public Stream { | ||
private: | ||
bool isBigEndian; | ||
|
||
public: | ||
ReadStream(bool bigEndian = LITTLE_ENDIAN) : isBigEndian(bigEndian) {} | ||
|
||
bool isBE() { return isBigEndian; } | ||
|
||
// End of stream interface | ||
virtual bool eos() const = 0; | ||
|
||
// Read interface | ||
virtual uint32 read(void *dataPtr, uint32 dataSize) = 0; | ||
|
||
byte readByte() { | ||
byte b = 0; | ||
read(&b, 1); | ||
return b; | ||
} | ||
|
||
uint16 readUint16() { | ||
uint16 val; | ||
read(&val, 2); | ||
return (isBigEndian) ? FROM_BE_16(val) : FROM_LE_16(val); | ||
} | ||
|
||
uint32 readUint32() { | ||
uint32 val; | ||
read(&val, 4); | ||
return (isBigEndian) ? FROM_BE_32(val) : FROM_LE_32(val); | ||
} | ||
|
||
uint64 readUint64() { | ||
uint64 val; | ||
read(&val, 8); | ||
return (isBigEndian) ? FROM_BE_64(val) : FROM_LE_64(val); | ||
} | ||
|
||
inline byte readSByte() { | ||
return (int8) readByte(); | ||
} | ||
|
||
inline int16 readSint16() { | ||
return (int16) readUint16(); | ||
} | ||
|
||
inline int32 readSint32() { | ||
return (int32) readUint32(); | ||
} | ||
|
||
inline int64 readSint64() { | ||
return (int64) readUint64(); | ||
} | ||
}; | ||
|
||
class SeekableReadStream : virtual public ReadStream { | ||
public: | ||
// Position of cursor | ||
virtual int64 pos() const = 0; | ||
|
||
// Size of stream | ||
virtual int64 size() const = 0; | ||
|
||
// Set the cursor to a specific place in stream | ||
// wrapper identical to fseek() | ||
virtual bool seek(int64 offset, int whence = SEEK_SET) = 0; | ||
|
||
// Skip given bytes in stream | ||
virtual bool skip(uint32 offset) { return seek(offset, SEEK_CUR); } | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include "common/stream.h" | ||
|
||
int main() | ||
{ | ||
char* k = new char[10]; | ||
printf_s("Hello World\n"); | ||
scanf_s(k); | ||
return 0; | ||
} | ||
|
||
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu | ||
// Debug program: F5 or Debug > Start Debugging menu | ||
|
||
// Tips for Getting Started: | ||
// 1. Use the Solution Explorer window to add/manage files | ||
// 2. Use the Team Explorer window to connect to source control | ||
// 3. Use the Output window to see build output and other messages | ||
// 4. Use the Error List window to view errors | ||
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project | ||
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file | ||
Comment on lines
+11
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove kek |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kinda risky, use https://cplusplus.com/reference/cstdint/ for full portability