diff --git a/HandmadeHero.10x b/HandmadeHero.10x index d2692bb..94c112b 100644 --- a/HandmadeHero.10x +++ b/HandmadeHero.10x @@ -45,6 +45,8 @@ Build_Debug Build_Development INTELLISENSE_DIRECTIVES=1 + _WIN64 + _MSC_VER diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index dd6f125..175f82d 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -7,7 +7,7 @@ #include "handmade.hpp" #include "tile_map.cpp" -#include "random.cpp +#include "random.cpp" #endif NS_ENGINE_BEGIN @@ -265,31 +265,42 @@ void draw_bitmap( OffscreenBuffer* buffer max_y = buffer_height; // Start with the pixel on the top left corner of the rectangle - u8* row = rcast(u8*, buffer->memory ) + u8* dst_row = rcast(u8*, buffer->memory ) + min_x * buffer->bytes_per_pixel + min_y * buffer->pitch; + u32* src_row = bitmap->pixels + bitmap->width * (bitmap->height - 1); - s32 bmp_y = bmp_start_y; for ( s32 y = min_y; y < max_y; ++ y ) { - s32* pixel_32 = rcast(s32*, row); + u32* dst = rcast(u32*, dst_row); + u32* src = src_row; - s32 bmp_x = bmp_start_x; for ( s32 x = min_x; x < max_x; ++ x ) { - u32 color = bitmap->pixels[ bmp_y * bitmap->width + bmp_x ]; + #define extract( pixel, shift ) (( *pixel >> shift ) & 0xFF) + f32 alpha = scast(f32, extract(src, 24)) / 255.f; - // TODO(Ed): This is a bad alpha check, fix it. - // if ( (color >> 24) != 0 ) - // { - *pixel_32 = color; - // } - ++ pixel_32; - ++ bmp_x; + f32 src_R = scast(f32, extract(src, 16)); + f32 src_G = scast(f32, extract(src, 8)); + f32 src_B = scast(f32, extract(src, 0)); + + f32 dst_R = scast(f32, extract(dst, 16)); + f32 dst_G = scast(f32, extract(dst, 8)); + f32 dst_B = scast(f32, extract(dst, 0)); + #undef extract + + f32 red = (1 - alpha) * dst_R + alpha * src_R; + f32 green = (1 - alpha) * dst_G + alpha * src_G; + f32 blue = (1 - alpha) * dst_B + alpha * src_B; + + *dst = u32(red + 0.5f) << 16 | u32(green + 0.5f) << 8 | u32(blue + 0.5f) << 0; + + ++ dst; + ++ src; } - row += buffer->pitch; - -- bmp_y; + dst_row += buffer->pitch; + src_row -= bitmap->width; } } @@ -321,8 +332,7 @@ Bitmap load_bmp( platform::ModuleAPI* platform_api, Str file_path ) } BitmapHeaderPacked* header = pcast(BitmapHeaderPacked*, file.data); - // Note: Byte order is in little-endian AA BB GG RR (bottom up) (ABGR) - // + assert( header->compression == 3 ); // TODO(Ed) : Do not directly assign this, allocate the pixels to somewhere in game or engine persistent. result.pixels = rcast(u32*, rcast(Byte*, file.data) + header->bitmap_offset); @@ -330,8 +340,22 @@ Bitmap load_bmp( platform::ModuleAPI* platform_api, Str file_path ) result.height = header->height; result.bits_per_pixel = header->bits_per_pixel; + u32 red_shift = 0; + u32 green_shift = 0; + u32 blue_shift = 0; + u32 alpha_shift = 0; + + b32 red_found = bitscan_forward( & red_shift, header->red_mask ); + b32 green_found = bitscan_forward( & green_shift, header->green_mask ); + b32 blue_found = bitscan_forward( & blue_shift, header->blue_mask ); + b32 alpha_found = bitscan_forward( & alpha_shift, ~(header->red_mask | header->green_mask | header->blue_mask) ); + + assert( red_found ); + assert( green_found ); + assert( blue_found ); + assert( alpha_found ); + u32* src = result.pixels; - // Note: Do not use this generically, code is bad) for ( s32 y = 0; y < header->width; ++ y ) { for ( s32 x = 0; x < header->height; ++ x ) @@ -345,9 +369,13 @@ Bitmap load_bmp( platform::ModuleAPI* platform_api, Str file_path ) }; Pixel* px = rcast(Pixel*, src); - Pixel cpy = *px; - // *src = (u32(px->Alpha) << 0) | (u32(px->Red) << 24) | (u32(px->Green) << 16) | (u32(px->Blue) << 8); - *src = (*src >> 8) | (*src << 24); + + u32 alpha = (( *src >> alpha_shift ) & 0xFF) << 24; + u32 red = (( *src >> red_shift ) & 0xFF) << 16; + u32 green = (( *src >> green_shift ) & 0xFF) << 8; + u32 blue = (( *src >> blue_shift ) & 0xFF) << 0; + + *src = alpha | red | green | blue; ++ src; } } diff --git a/project/platform/grime.hpp b/project/platform/grime.hpp index 501eaf1..c78f3a3 100644 --- a/project/platform/grime.hpp +++ b/project/platform/grime.hpp @@ -15,36 +15,30 @@ /* Platform OS */ #if defined( _WIN32 ) || defined( _WIN64 ) -# ifndef SYSTEM_WINDOWS -# define SYSTEM_WINDOWS 1 +# ifndef System_Windows +# define System_Windows 1 # endif #elif defined( __APPLE__ ) && defined( __MACH__ ) -# ifndef SYSTEM_OSX -# define SYSTEM_OSX 1 +# ifndef System_OSX +# define System_OSX 1 # endif -# ifndef SYSTEM_MACOS -# define SYSTEM_MACOS 1 -# endif -# include -# if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1 -# ifndef SYSTEM_IOS -# define SYSTEM_IOS 1 -# endif +# ifndef System_MacOS +# define System_MacOS 1 # endif #elif defined( __unix__ ) -# ifndef SYSTEM_UNIX -# define GEN_SYSTEM_UNIX 1 +# ifndef System_Unix +# define System_Unix 1 # endif # if defined( ANDROID ) || defined( __ANDROID__ ) -# ifndef SYSTEM_ANDROID -# define SYSTEM_ANDROID 1 +# ifndef System_Android +# define System_Android 1 # endif # ifndef SYSTEM_LINUX -# define SYSTEM_LINUX 1 +# define System_Linux 1 # endif # elif defined( __linux__ ) -# ifndef SYSTEM_LINUX -# define SYSTEM_LINUX 1 +# ifndef System_Linux +# define System_linux 1 # endif # else # error This UNIX operating system is not supported @@ -56,11 +50,11 @@ /* Platform compiler */ #if defined( _MSC_VER ) -# define COMPILER_MSVC 1 +# define Compiler_MSVC 1 #elif defined( __clang__ ) -# define COMPILER_CLANG 1 +# define Compiler_Clang 1 #else -# error Unknown compiler +# error "Unknown compiler" #endif #if defined( __has_attribute ) @@ -76,7 +70,7 @@ # include # include -# if defined( SYSTEM_WINDOWS ) +# if defined( System_Windows ) # include # endif diff --git a/project/platform/intrinsics.hpp b/project/platform/intrinsics.hpp index 3ab532b..5fe8b28 100644 --- a/project/platform/intrinsics.hpp +++ b/project/platform/intrinsics.hpp @@ -2,6 +2,7 @@ #if INTELLISENSE_DIRECTIVES #include +#include "grime.hpp" #endif // TODO(Ed) : Convert all of these to platform-efficient versions @@ -33,21 +34,50 @@ s32 truncate( f32 value ) return result; } -inline +inline f32 sine( f32 angle ) { f32 result = sinf( angle ); return result; } +inline f32 cosine( f32 angle ) { f32 result = cosf( angle ); return result; } +inline f32 arc_tangent( f32 Y, f32 X ) { f32 result = atan2f( Y, X ); return result; } + +inline +b32 bitscan_forward( u32* index, u32 value ) +{ + b32 found = false; + + // TODO(Ed) : This file can technically be generated with a metaprogram or via the preprocessor.. + // We can keep The definitions for each of these based on the platform and + // Choose which one gets added to te project that way (keeps the runtime definition clean) +#if Compiler_MSVC + found = _BitScanForward( rcast(unsigned long*, index), value ); +#elif Compiler_Clang + *index = __builtin_ctz( value ); + found = index; +#else + for ( u32 test = 0; test < 32; ++ test ) + { + if ( value & (1 << test )) + { + *index = test; + found = true; + break; + } + } +#endif + return found; +} diff --git a/project/platform/jsl.hpp b/project/platform/jsl.hpp index 992a562..a2e12da 100644 --- a/project/platform/jsl.hpp +++ b/project/platform/jsl.hpp @@ -3,18 +3,18 @@ // Joyshock grime wrapper // JoyShock does not provide a proper c-linkage definition for its structs, so we have to push this warning ignore. -#ifdef COMPILER_CLANG +#ifdef Compiler_Clang # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wreturn-type-c-linkage" -#elif COMPILER_MSVC +#elif Compiler_MSVC # pragma warning( push ) # pragma warning( disable: 4820 ) #endif #include "dependencies/JoyShockLibrary/JoyShockLibrary.h" -#ifdef COMPILER_CLANG +#ifdef Compiler_Clang # pragma clang diagnostic pop -#elif COMPILER_MSVC +#elif Compiler_MSVC # pragma warning( pop ) #endif