mirror of
				https://github.com/Ed94/HandmadeHero.git
				synced 2025-10-31 06:50:54 -07:00 
			
		
		
		
	Day 8 complete.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -31,7 +31,9 @@ | |||||||
| 		"xhash": "cpp", | 		"xhash": "cpp", | ||||||
| 		"shared_mutex": "cpp", | 		"shared_mutex": "cpp", | ||||||
| 		"mutex": "cpp", | 		"mutex": "cpp", | ||||||
| 		"system_error": "cpp" | 		"system_error": "cpp", | ||||||
|  | 		"ios": "cpp", | ||||||
|  | 		"xiosbase": "cpp" | ||||||
| 	}, | 	}, | ||||||
| 	"C_Cpp.intelliSenseEngineFallback": "disabled", | 	"C_Cpp.intelliSenseEngineFallback": "disabled", | ||||||
| 	"C_Cpp.errorSquiggles": "enabled", | 	"C_Cpp.errorSquiggles": "enabled", | ||||||
|   | |||||||
| @@ -70,11 +70,13 @@ struct WinDimensions | |||||||
| global OffscreenBuffer BackBuffer; | global OffscreenBuffer BackBuffer; | ||||||
| global WinDimensions   WindowDimensions; | global WinDimensions   WindowDimensions; | ||||||
|  |  | ||||||
|  | global LPDIRECTSOUNDBUFFER DS_SecondaryBuffer; | ||||||
|  | global s32                 DS_SecondaryBufferSize; | ||||||
|  |  | ||||||
| HRESULT WINAPI | HRESULT WINAPI | ||||||
| DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN  pUnkOuter ); | DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN  pUnkOuter ); | ||||||
|  |  | ||||||
| using DirectSoundCreateFn = HRESULT WINAPI (LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN  pUnkOuter ); | using DirectSoundCreateFn = HRESULT WINAPI (LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN  pUnkOuter ); | ||||||
|  |  | ||||||
| global DirectSoundCreateFn* direct_sound_create; | global DirectSoundCreateFn* direct_sound_create; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -91,7 +93,7 @@ init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size ) | |||||||
|  |  | ||||||
| 	// Get direct sound object | 	// Get direct sound object | ||||||
| 	direct_sound_create = rcast( DirectSoundCreateFn*, GetProcAddress( sound_library, "DirectSoundCreate" )); | 	direct_sound_create = rcast( DirectSoundCreateFn*, GetProcAddress( sound_library, "DirectSoundCreate" )); | ||||||
| 	if ( ! ensure(direct_sound_create, "Failed to get direct_sound_create_procedure" ) ) | 	if ( ! ensure( direct_sound_create, "Failed to get direct_sound_create_procedure" ) ) | ||||||
| 	{ | 	{ | ||||||
| 		// TOOD : Diagnostic | 		// TOOD : Diagnostic | ||||||
| 		return; | 		return; | ||||||
| @@ -102,7 +104,6 @@ init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size ) | |||||||
| 	{ | 	{ | ||||||
| 		// TODO : Diagnostic | 		// TODO : Diagnostic | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( ! SUCCEEDED( direct_sound->SetCooperativeLevel(window_handle, DSSCL_PRIORITY) ) ) | 	if ( ! SUCCEEDED( direct_sound->SetCooperativeLevel(window_handle, DSSCL_PRIORITY) ) ) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO : Diagnostic | 		// TODO : Diagnostic | ||||||
| @@ -133,33 +134,22 @@ init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size ) | |||||||
| 		{ | 		{ | ||||||
| 			// TODO : Diagnostic | 			// TODO : Diagnostic | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Format is finally set! |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	LPDIRECTSOUNDBUFFER secondary_buffer; |  | ||||||
| 	{ |  | ||||||
| 	DSBUFFERDESC | 	DSBUFFERDESC | ||||||
| 	buffer_description { sizeof(buffer_description) }; | 	buffer_description { sizeof(buffer_description) }; | ||||||
| 	buffer_description.dwFlags       = 0; | 	buffer_description.dwFlags       = 0; | ||||||
| 	buffer_description.dwBufferBytes = buffer_size; | 	buffer_description.dwBufferBytes = buffer_size; | ||||||
| 	buffer_description.lpwfxFormat   = & wave_format; | 	buffer_description.lpwfxFormat   = & wave_format; | ||||||
|  |  | ||||||
| 		if ( ! SUCCEEDED( direct_sound->CreateSoundBuffer( & buffer_description, & secondary_buffer, 0 ) )) | 	if ( ! SUCCEEDED( direct_sound->CreateSoundBuffer( & buffer_description, & DS_SecondaryBuffer, 0 ) )) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO : Diagnostic | 		// TODO : Diagnostic | ||||||
| 	} | 	} | ||||||
| 		if ( ! SUCCEEDED( secondary_buffer->SetFormat( & wave_format ) ) ) | 	if ( ! SUCCEEDED( DS_SecondaryBuffer->SetFormat( & wave_format ) ) ) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO : Diagnostic | 		// TODO : Diagnostic | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Create primary buffer |  | ||||||
|  |  | ||||||
| 	// Create secondary buffer |  | ||||||
|  |  | ||||||
| 	// Start playing |  | ||||||
| } | } | ||||||
|  |  | ||||||
| internal WinDimensions | internal WinDimensions | ||||||
| @@ -448,15 +438,13 @@ WinMain( | |||||||
| 		for ( u32 jsl_device_index = 0; jsl_device_index < jsl_num_devices; ++ jsl_device_index ) | 		for ( u32 jsl_device_index = 0; jsl_device_index < jsl_num_devices; ++ jsl_device_index ) | ||||||
| 		{ | 		{ | ||||||
| 			JslSetLightColour( device_handles[ jsl_device_index ], (255 << 8) ); | 			JslSetLightColour( device_handles[ jsl_device_index ], (255 << 8) ); | ||||||
| 			do_once_start |  | ||||||
| 				congrats( "GOT THE CONTROLLER BOIS" ); |  | ||||||
| 			do_once_end |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information ); | 	// MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information ); | ||||||
|  |  | ||||||
| 	WNDCLASS window_class {}; | 	WNDCLASS | ||||||
|  | 	window_class {}; | ||||||
| 	window_class.style = CS_Horizontal_Redraw | CS_Vertical_Redraw; | 	window_class.style = CS_Horizontal_Redraw | CS_Vertical_Redraw; | ||||||
| 	window_class.lpfnWndProc = main_window_callback; | 	window_class.lpfnWndProc = main_window_callback; | ||||||
| 	// window_class.cbClsExtra  = ; | 	// window_class.cbClsExtra  = ; | ||||||
| @@ -468,67 +456,96 @@ WinMain( | |||||||
| 	window_class.lpszMenuName  = L"Handmade Hero!"; | 	window_class.lpszMenuName  = L"Handmade Hero!"; | ||||||
| 	window_class.lpszClassName = L"HandmadeHeroWindowClass"; | 	window_class.lpszClassName = L"HandmadeHeroWindowClass"; | ||||||
|  |  | ||||||
| 	if ( RegisterClassW( & window_class ) ) | 	if ( ! RegisterClassW( & window_class ) ) | ||||||
| 	{ | 	{ | ||||||
|  | 		// TODO : Diagnostic Logging | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	HWND window_handle = CreateWindowExW( | 	HWND window_handle = CreateWindowExW( | ||||||
| 		0, | 		0, | ||||||
| 		window_class.lpszClassName, | 		window_class.lpszClassName, | ||||||
| 		L"Handmade Hero", | 		L"Handmade Hero", | ||||||
| 		WS_Overlapped_Window | WS_Initially_Visible, | 		WS_Overlapped_Window | WS_Initially_Visible, | ||||||
| 			CW_USEDEFAULT, CW_USEDEFAULT, // x, y | 		CW_Use_Default, CW_Use_Default, // x, y | ||||||
| 			CW_USEDEFAULT, CW_USEDEFAULT, // width, height | 		CW_Use_Default, CW_Use_Default, // width, height | ||||||
| 		0, 0,                         // parent, menu | 		0, 0,                         // parent, menu | ||||||
| 		instance, 0                   // instance, param | 		instance, 0                   // instance, param | ||||||
| 	); | 	); | ||||||
|  |  | ||||||
| 		if ( window_handle ) | 	if ( ! window_handle ) | ||||||
| 	{ | 	{ | ||||||
|  | 		// TODO : Diagnostic Logging | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	Running = true; | 	Running = true; | ||||||
|  |  | ||||||
| 	WinDimensions dimensions = get_window_dimensions( window_handle ); | 	WinDimensions dimensions = get_window_dimensions( window_handle ); | ||||||
| 	resize_dib_section( &BackBuffer, 1280, 720 ); | 	resize_dib_section( &BackBuffer, 1280, 720 ); | ||||||
|  |  | ||||||
| 			init_sound( window_handle, 48000, 48000 * sizeof(s16) * 2 ); | 	s32 ds_samples            = 48000; | ||||||
|  | 	s32 ds_samples_per_second = ds_samples * sizeof(s16) * 2; | ||||||
|  | 	s32 ds_bytes_per_sample   = sizeof(s16) * 2; | ||||||
|  | 	DS_SecondaryBufferSize	  = ds_samples_per_second * ds_bytes_per_sample; | ||||||
|  |  | ||||||
| 			MSG  msg_info; | 	init_sound( window_handle, ds_samples, DS_SecondaryBufferSize ); | ||||||
|  |  | ||||||
|  | 	// Graphics & Input Test | ||||||
| 	u32 x_offset = 0; | 	u32 x_offset = 0; | ||||||
| 	u32 y_offset = 0; | 	u32 y_offset = 0; | ||||||
|  |  | ||||||
|  | 	// Controller State | ||||||
| 	bool xinput_detected = false; | 	bool xinput_detected = false; | ||||||
|  |  | ||||||
| 			// Controller State | 	u32 dpad_up        = false; | ||||||
| 			u8 dpad_up        = false; | 	u32 dpad_down      = false; | ||||||
| 			u8 dpad_down      = false; | 	u32 dpad_left      = false; | ||||||
| 			u8 dpad_left      = false; | 	u32 dpad_right     = false; | ||||||
| 			u8 dpad_right     = false; | 	u32 start          = false; | ||||||
| 			u8 start          = false; | 	u32 back           = false; | ||||||
| 			u8 back           = false; | 	u32 left_shoulder  = false; | ||||||
| 			u8 left_shoulder  = false; | 	u32 right_shoulder = false; | ||||||
| 			u8 right_shoulder = false; | 	u32 btn_a_button   = false; | ||||||
| 			u8 btn_a_button   = false; | 	u32 btn_b_button   = false; | ||||||
| 			u8 btn_b_button   = false; | 	u32 btn_x_button   = false; | ||||||
| 			u8 btn_x_button   = false; | 	u32 btn_y_button   = false; | ||||||
| 			u8 btn_y_button   = false; | 	u16 stick_left_x  = 0; | ||||||
| 			u16 left_stick_x  = 0; | 	u16 stick_left_y  = 0; | ||||||
| 			u16 left_stick_y  = 0; | 	u16 stick_right_x = 0; | ||||||
| 			u16 right_stick_x = 0; | 	u16 stick_right_y = 0; | ||||||
| 			u16 right_stick_y = 0; |  | ||||||
|  | 	// Square Wave - Sound Test | ||||||
|  | 	u32 ds_running_sample_index = 0; | ||||||
|  | 	s32 square_wave_tone_hz 	= 262; | ||||||
|  | 	s32 square_wave_period      = ds_samples_per_second / square_wave_tone_hz; | ||||||
|  | 	s32 half_square_wave_period = square_wave_period / 2; | ||||||
|  | 	s32 square_wave_tone_volume = 3000; | ||||||
|  |  | ||||||
|  | 	// TODO : Add sine wave test | ||||||
|  |  | ||||||
|  | 	// Windows | ||||||
|  | 	MSG window_msg_info; | ||||||
|  |  | ||||||
| 	while( Running ) | 	while( Running ) | ||||||
| 	{ | 	{ | ||||||
| 				if ( PeekMessageW( & msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) ) | 		// Window Management | ||||||
| 		{ | 		{ | ||||||
| 					if ( msg_info.message == WM_QUIT  ) | 			if ( PeekMessageW( & window_msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) ) | ||||||
|  | 			{ | ||||||
|  | 				if ( window_msg_info.message == WM_QUIT  ) | ||||||
| 				{ | 				{ | ||||||
| 					OutputDebugStringA("WM_QUIT\n"); | 					OutputDebugStringA("WM_QUIT\n"); | ||||||
| 					Running = false; | 					Running = false; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 					TranslateMessage( & msg_info ); | 				TranslateMessage( & window_msg_info ); | ||||||
| 					DispatchMessageW( & msg_info ); | 				DispatchMessageW( & window_msg_info ); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		// Input | ||||||
|  | 		{ | ||||||
| 			// XInput Polling | 			// XInput Polling | ||||||
| 			// TODO(Ed) : Should we poll this more frequently? | 			// TODO(Ed) : Should we poll this more frequently? | ||||||
| 			for ( DWORD controller_index = 0; controller_index < XUSER_MAX_COUNT; ++ controller_index ) | 			for ( DWORD controller_index = 0; controller_index < XUSER_MAX_COUNT; ++ controller_index ) | ||||||
| @@ -552,10 +569,10 @@ WinMain( | |||||||
| 					btn_x_button   = pad->wButtons & XINPUT_GAMEPAD_X; | 					btn_x_button   = pad->wButtons & XINPUT_GAMEPAD_X; | ||||||
| 					btn_y_button   = pad->wButtons & XINPUT_GAMEPAD_Y; | 					btn_y_button   = pad->wButtons & XINPUT_GAMEPAD_Y; | ||||||
|  |  | ||||||
| 						left_stick_x  = pad->sThumbLX; | 					stick_left_x  = pad->sThumbLX; | ||||||
| 						left_stick_y  = pad->sThumbLY; | 					stick_left_y  = pad->sThumbLY; | ||||||
| 						right_stick_x = pad->sThumbRX; | 					stick_right_x = pad->sThumbRX; | ||||||
| 						right_stick_y = pad->sThumbRY; | 					stick_right_y = pad->sThumbRY; | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| @@ -585,6 +602,11 @@ WinMain( | |||||||
| 				btn_b_button   = state.buttons & JSMASK_E; | 				btn_b_button   = state.buttons & JSMASK_E; | ||||||
| 				btn_x_button   = state.buttons & JSMASK_W; | 				btn_x_button   = state.buttons & JSMASK_W; | ||||||
| 				btn_y_button   = state.buttons & JSMASK_N; | 				btn_y_button   = state.buttons & JSMASK_N; | ||||||
|  |  | ||||||
|  | 				stick_left_x  = state.stickLX; | ||||||
|  | 				stick_left_y  = state.stickLY; | ||||||
|  | 				stick_right_x = state.stickRX; | ||||||
|  | 				stick_right_y = state.stickRY; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			x_offset += dpad_right; | 			x_offset += dpad_right; | ||||||
| @@ -620,7 +642,10 @@ WinMain( | |||||||
| 					JslSetRumble( 0, 0, 0 ); | 					JslSetRumble( 0, 0, 0 ); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Rendering | ||||||
|  | 		{ | ||||||
| 			render_weird_graident( &BackBuffer, x_offset, y_offset ); | 			render_weird_graident( &BackBuffer, x_offset, y_offset ); | ||||||
|  |  | ||||||
| 			WinDimensions dimensions     = get_window_dimensions( window_handle ); | 			WinDimensions dimensions     = get_window_dimensions( window_handle ); | ||||||
| @@ -629,15 +654,97 @@ WinMain( | |||||||
| 				, 0, 0 | 				, 0, 0 | ||||||
| 				, dimensions.Width, dimensions.Height ); | 				, dimensions.Width, dimensions.Height ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		// Audio | ||||||
|  | 		do { | ||||||
|  | 			if ( btn_y_button ) | ||||||
|  | 			{ | ||||||
|  | 				square_wave_tone_volume += 10; | ||||||
|  | 			} | ||||||
|  | 			if ( btn_b_button ) | ||||||
|  | 			{ | ||||||
|  | 				square_wave_tone_volume -= 10; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			DWORD ds_play_cursor; | ||||||
|  | 			DWORD ds_write_cursor; | ||||||
|  | 			if ( ! SUCCEEDED( DS_SecondaryBuffer->GetCurrentPosition( & ds_play_cursor, & ds_write_cursor ) )) | ||||||
|  | 			{ | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			DWORD byte_to_lock   = ds_running_sample_index * ds_bytes_per_sample % DS_SecondaryBufferSize; | ||||||
|  | 			DWORD bytes_to_write; | ||||||
|  | 			if ( byte_to_lock == ds_play_cursor ) | ||||||
|  | 			{ | ||||||
|  | 				// At play cursor | ||||||
|  | 				bytes_to_write = DS_SecondaryBufferSize; | ||||||
|  | 			} | ||||||
|  | 			else if ( byte_to_lock > ds_play_cursor) | ||||||
|  | 			{ | ||||||
|  | 				// Infront of play cursor |--play--byte_to_write-->--| | ||||||
|  | 				bytes_to_write = DS_SecondaryBufferSize - byte_to_lock; | ||||||
|  | 				bytes_to_write += ds_play_cursor; | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 			// TODO(Ed) : Logging | 				// Behind play cursor |--byte_to_write-->--play--| | ||||||
|  | 				bytes_to_write = ds_play_cursor - byte_to_lock; | ||||||
| 			} | 			} | ||||||
| 	} |  | ||||||
| 	else | 			bytes_to_write = max(bytes_to_write, 1); | ||||||
|  |  | ||||||
|  | 			LPVOID region_1; | ||||||
|  | 			DWORD  region_1_size; | ||||||
|  | 			LPVOID region_2; | ||||||
|  | 			DWORD  region_2_size; | ||||||
|  |  | ||||||
|  | 			HRESULT ds_lock_result = DS_SecondaryBuffer->Lock( byte_to_lock, bytes_to_write | ||||||
|  | 				, & region_1, & region_1_size | ||||||
|  | 				, & region_2, & region_2_size | ||||||
|  | 				, 0 ); | ||||||
|  | 			if ( ! SUCCEEDED( ds_lock_result ) ) | ||||||
| 			{ | 			{ | ||||||
| 		// TODO(Ed) : Logging | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// TODO : Assert that region sizes are valid | ||||||
|  |  | ||||||
|  | 			// TODO : Collapse these loops | ||||||
|  | 			DWORD region_1_sample_count = region_1_size / ds_bytes_per_sample; | ||||||
|  | 			s16* sample_out = rcast( s16*, region_1 ); | ||||||
|  | 			for ( DWORD sample_index = 0; sample_index < region_1_sample_count; ++ sample_index ) | ||||||
|  | 			{ | ||||||
|  | 				s16 sample_value = (ds_running_sample_index /  half_square_wave_period) % 2 ? | ||||||
|  | 					square_wave_tone_volume : -square_wave_tone_volume; | ||||||
|  | 				++ ds_running_sample_index; | ||||||
|  |  | ||||||
|  | 				*sample_out = sample_value; | ||||||
|  | 				++ sample_out; | ||||||
|  |  | ||||||
|  | 				*sample_out = sample_value; | ||||||
|  | 				++ sample_out; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			DWORD region_2_sample_count = region_2_size / ds_bytes_per_sample; | ||||||
|  | 			sample_out = rcast( s16*, region_2 ); | ||||||
|  | 			for ( DWORD sample_index = 0; sample_index < region_2_sample_count; ++ sample_index ) | ||||||
|  | 			{ | ||||||
|  | 				s16 sample_value = (ds_running_sample_index / half_square_wave_period) % 2 ? | ||||||
|  | 					square_wave_tone_volume : -square_wave_tone_volume; | ||||||
|  | 				++ ds_running_sample_index; | ||||||
|  |  | ||||||
|  | 				*sample_out = sample_value; | ||||||
|  | 				++ sample_out; | ||||||
|  |  | ||||||
|  | 				*sample_out = sample_value; | ||||||
|  | 				++ sample_out; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			DS_SecondaryBuffer->Unlock( region_1, region_1_size, region_2, region_2_size ); | ||||||
|  |  | ||||||
|  | 			DS_SecondaryBuffer->Play( 0, 0, DSBPLAY_LOOPING ); | ||||||
|  | 		} while(0); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( jsl_num_devices > 0 ) | 	if ( jsl_num_devices > 0 ) | ||||||
|   | |||||||
| @@ -52,6 +52,11 @@ enum CS : UINT | |||||||
| 	CS_Vertical_Redraw    = CS_VREDRAW, | 	CS_Vertical_Redraw    = CS_VREDRAW, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum CW : s32 | ||||||
|  | { | ||||||
|  | 	CW_Use_Default = CW_USEDEFAULT, | ||||||
|  | }; | ||||||
|  |  | ||||||
| enum DIB : UINT | enum DIB : UINT | ||||||
| { | { | ||||||
| 	DIB_ColorTable_RGB     = 0, | 	DIB_ColorTable_RGB     = 0, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user