mirror of
https://github.com/libretro/cpp-cheat.git
synced 2025-04-12 08:14:07 +00:00
sync
This commit is contained in:
parent
1155e8dd90
commit
9c088e08db
@ -61,6 +61,9 @@
|
||||
1. [valarray](valarray.cpp)
|
||||
1. [deque](deque.cpp)
|
||||
1. [string](string.cpp)
|
||||
1. IO
|
||||
1. [sstream](sstream.cpp)
|
||||
1. [iostream](iostream.cpp)
|
||||
1. [thread](thread.cpp)
|
||||
1. [sleep_for](sleep_for.cpp)
|
||||
1. [atomic](atomic.cpp)
|
||||
|
80
cpp/iostream.cpp
Normal file
80
cpp/iostream.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "common.hpp"
|
||||
|
||||
int main() {
|
||||
/*
|
||||
# cout
|
||||
|
||||
stdout.
|
||||
|
||||
`ostream` object.
|
||||
|
||||
For tests, std::stringstream shall be used as the results can then be tested,
|
||||
and the behaviour is identical to cout.
|
||||
|
||||
`<<` is very magic. You need to understand:
|
||||
|
||||
- operator overload
|
||||
- function template argument deduction
|
||||
- namespaces adl
|
||||
|
||||
before really understanding why it works.
|
||||
|
||||
# cerr
|
||||
|
||||
Cout for stderr
|
||||
|
||||
# clog
|
||||
|
||||
By default also points to stderr, but can be redirected with TODO.
|
||||
*/
|
||||
{
|
||||
std::cout << "cout" << std::endl;
|
||||
std::cerr << "cerr" << std::endl;
|
||||
std::clog << "clog" << std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
# cin
|
||||
|
||||
# stdin
|
||||
|
||||
`istream` object.
|
||||
|
||||
Avoid using it for similar reasons as scanf:
|
||||
|
||||
- hard to handle invalid inputs
|
||||
- difficult to predict behaviour
|
||||
|
||||
getline is the best option.
|
||||
*/
|
||||
{
|
||||
//std::cout << "Enter an integer:" << endl;
|
||||
//std::cin >> i;
|
||||
//std::cout << i << std::endl;
|
||||
}
|
||||
|
||||
// This is how a very explicit usage of `<<` would look like
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
//TODO0 how to get his working?
|
||||
//std::operator<<<std::ostream,std::string>(ss, "explicit");
|
||||
|
||||
std::operator<<(std::operator<<(ss, "explicit "), "call");
|
||||
}
|
||||
|
||||
/*
|
||||
# cout unsigned char
|
||||
|
||||
Prints literal bytes.
|
||||
|
||||
http://stackoverflow.com/questions/19562103/uint8-t-cant-be-printed-with-cout/19562163#19562163
|
||||
*/
|
||||
{
|
||||
std::cout << (unsigned char)1 << std::endl;
|
||||
std::cout << (char)1 << std::endl;
|
||||
std::cout << (signed char)1 << std::endl;
|
||||
std::cout << (int)1 << std::endl;
|
||||
std::cout << (unsigned int)1 << std::endl;
|
||||
}
|
||||
}
|
61
cpp/main.cpp
61
cpp/main.cpp
@ -286,67 +286,6 @@ int main() {
|
||||
|
||||
*/
|
||||
{
|
||||
/*
|
||||
# cout
|
||||
|
||||
stdout.
|
||||
|
||||
`ostream` object.
|
||||
|
||||
For tests, std::stringstream shall be used as the results can then be tested,
|
||||
and the behaviour is identical to cout.
|
||||
|
||||
`<<` is very magic. You need to understand:
|
||||
|
||||
- operator overload
|
||||
- function template argument deduction
|
||||
- namespaces adl
|
||||
|
||||
before really understanding why it works.
|
||||
|
||||
# cerr
|
||||
|
||||
Cout for stderr
|
||||
|
||||
# clog
|
||||
|
||||
By default also points to stderr, but can be redirected with TODO.
|
||||
*/
|
||||
{
|
||||
std::cout << "cout" << std::endl;
|
||||
std::cerr << "cerr" << std::endl;
|
||||
std::clog << "clog" << std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
# cin
|
||||
|
||||
# stdin
|
||||
|
||||
`istream` object.
|
||||
|
||||
Avoid using it for similar reasons as scanf:
|
||||
|
||||
- hard to handle invalid inputs
|
||||
- difficult to predict behaviour
|
||||
|
||||
getline is the best option.
|
||||
*/
|
||||
{
|
||||
//std::cout << "Enter an integer:" << endl;
|
||||
//std::cin >> i;
|
||||
//std::cout << i << std::endl;
|
||||
}
|
||||
|
||||
// This is how a very explicit usage of `<<` would look like
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
//TODO0 how to get his working?
|
||||
//std::operator<<<std::ostream,std::string>(ss, "explicit");
|
||||
|
||||
std::operator<<(std::operator<<(ss, "explicit "), "call");
|
||||
}
|
||||
|
||||
// #<< left shift overload
|
||||
{
|
||||
|
81
cpp/sstream.cpp
Normal file
81
cpp/sstream.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "common.hpp"
|
||||
|
||||
int main() {
|
||||
/*
|
||||
# stringstream
|
||||
|
||||
# basic_stringstream
|
||||
|
||||
http://en.cppreference.com/w/cpp/io/basic_stringstream
|
||||
|
||||
An iostream String backed implementation.
|
||||
|
||||
The following is defined:
|
||||
|
||||
typedef basic_stringstream<char> stringstream;
|
||||
|
||||
Very useful to test streams without creating files / stdin.
|
||||
|
||||
# ostringstream
|
||||
|
||||
TODO vs stringstream.
|
||||
|
||||
http://stackoverflow.com/questions/3292107/whats-the-difference-between-istringstream-ostringstream-and-stringstream-w
|
||||
*/
|
||||
{
|
||||
// Initialize
|
||||
{
|
||||
{
|
||||
std::stringstream ss("");
|
||||
ss << "ab";
|
||||
ss << "cd";
|
||||
assert(ss.str() == "abcd");
|
||||
}
|
||||
|
||||
// empty constructor: TODO everything fails to compile. Why?
|
||||
{
|
||||
std::stringstream ss();
|
||||
//ss << "ab";
|
||||
//ss << "cd";
|
||||
//assert(ss.str() == "abcd");
|
||||
}
|
||||
|
||||
// Nope, works like a file that has come content.
|
||||
// http://stackoverflow.com/questions/3840531/what-is-the-purpose-of-ostringstreams-string-constructor
|
||||
{
|
||||
std::stringstream ss("ab");
|
||||
ss << "cd";
|
||||
assert(ss.str() == "cd");
|
||||
}
|
||||
|
||||
// ostringstream + ate
|
||||
{
|
||||
std::ostringstream ss("ab", std::ios::ate);
|
||||
ss << "cd";
|
||||
assert(ss.str() == "abcd");
|
||||
}
|
||||
|
||||
// stringstream + ate: TODO fails, why?
|
||||
{
|
||||
std::stringstream ss("ab", std::ios::ate);
|
||||
ss << "cd";
|
||||
assert(ss.str() == "ab");
|
||||
}
|
||||
}
|
||||
|
||||
// Clear
|
||||
{
|
||||
std::stringstream ss("");
|
||||
// Clear stringstream
|
||||
// http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
|
||||
ss.str("");
|
||||
// Clear flags. Very important, not only for error indicators but also for end of stream.
|
||||
ss.clear();
|
||||
assert(ss.str() == "");
|
||||
|
||||
// ERROR: use of deleted function because the constructor is =delete.
|
||||
//ss = std::stringstream();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -217,38 +217,6 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
# stringstream
|
||||
|
||||
# basic_stringstream
|
||||
|
||||
An iostream String backed implementation.
|
||||
|
||||
The following is defined:
|
||||
|
||||
typedef basic_stringstream<char> stringstream;
|
||||
|
||||
typedef basic_stringstream<char>
|
||||
|
||||
Very useful to test streams without creating files / stdin.
|
||||
*/
|
||||
{
|
||||
std::stringstream oss("abcd");
|
||||
|
||||
// str does not clear the std::stringstream object
|
||||
assert(oss.str() == "abcd");
|
||||
|
||||
// To clear it you could do: http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
|
||||
// Set to empty:
|
||||
oss.str("");
|
||||
// Clear flags. Very important, not only for error indicators but also for end of stream.
|
||||
oss.clear();
|
||||
assert(oss.str() == "");
|
||||
|
||||
// ERROR: use of deleted function because the constructor is =delete.
|
||||
//oss = std::stringstream();
|
||||
}
|
||||
|
||||
// Possible application: build up a huge string step by step.
|
||||
// May be more efficient than concatenations which always generates new objects.
|
||||
{
|
||||
@ -263,7 +231,7 @@ int main() {
|
||||
|
||||
There are a few standard alternatives.
|
||||
|
||||
<http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c>
|
||||
http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c
|
||||
*/
|
||||
{
|
||||
/*
|
||||
@ -299,8 +267,11 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
// #int to string
|
||||
// http://stackoverflow.com/questions/7663709/convert-string-to-int-c
|
||||
/*
|
||||
# string to int
|
||||
|
||||
http://stackoverflow.com/questions/7663709/convert-string-to-int-c
|
||||
*/
|
||||
{
|
||||
// Best C++11 error checking option: stoi
|
||||
#if __cplusplus >= 201103L
|
||||
|
@ -10,6 +10,7 @@
|
||||
1. [Animation](animation.c)
|
||||
1. [Animation user control](animation_user_control.c)
|
||||
1. [Animation user control discrete](animation_user_control_discrete.c)
|
||||
1. [Two player discrete](two_player_discrete.c)
|
||||
1. [Animation random walk](animation_random_walk.c)
|
||||
1. [Plane wave](plane_wave.c)
|
||||
1. [TTF](ttf.c)
|
||||
|
205
sdl/two_player_discrete.c
Normal file
205
sdl/two_player_discrete.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
Player movements are not synchronized.
|
||||
|
||||
To do so, we could:
|
||||
|
||||
- discretize time into time windows
|
||||
- check if a keypress was done in a time slot
|
||||
- update all players at once
|
||||
|
||||
but that would lead to a delay between keypress and movement.
|
||||
|
||||
If the time windows are very small, the delay cannot be seen,
|
||||
but then the players would move too fast in this discrete world.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#define WINDOW_WIDTH 600
|
||||
#define RECTS_PER_WINDOW (10)
|
||||
#define RECT_WIDTH (WINDOW_WIDTH / RECTS_PER_WINDOW)
|
||||
#define SCREENS_PER_SECOND 1.0
|
||||
#define MOVE_DELAY_NORMAL 0.25
|
||||
#define MOVE_DELAY_FAST (MOVE_DELAY_NORMAL / 4.0)
|
||||
|
||||
typedef struct {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
int speed_x;
|
||||
int speed_y;
|
||||
double last_move_time_s;
|
||||
} PlayerState;
|
||||
|
||||
unsigned int get_pos(int x, int speed) {
|
||||
x = (x + speed) % RECTS_PER_WINDOW;
|
||||
if (x < 0)
|
||||
x += RECTS_PER_WINDOW;
|
||||
return x;
|
||||
}
|
||||
|
||||
void draw_player(
|
||||
SDL_Renderer *renderer,
|
||||
PlayerState *player_state,
|
||||
double current_time_s,
|
||||
double move_delay,
|
||||
unsigned int r,
|
||||
unsigned int g,
|
||||
unsigned int b) {
|
||||
SDL_Rect rect;
|
||||
rect.w = RECT_WIDTH;
|
||||
rect.h = RECT_WIDTH;
|
||||
if ((player_state->speed_x || player_state->speed_y) && current_time_s - player_state->last_move_time_s > move_delay) {
|
||||
player_state->x = get_pos(player_state->x, player_state->speed_x);
|
||||
player_state->y = get_pos(player_state->y, player_state->speed_y);
|
||||
player_state->last_move_time_s = current_time_s;
|
||||
}
|
||||
rect.x = player_state->x * RECT_WIDTH;
|
||||
rect.y = player_state->y * RECT_WIDTH;
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, 255);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
}
|
||||
|
||||
void init_state(
|
||||
PlayerState *player_state_0,
|
||||
PlayerState *player_state_1,
|
||||
double *move_delay) {
|
||||
*move_delay = MOVE_DELAY_NORMAL;
|
||||
player_state_0->x = RECTS_PER_WINDOW / 5;
|
||||
player_state_0->y = RECTS_PER_WINDOW / 2;
|
||||
player_state_0->speed_x = 0;
|
||||
player_state_0->speed_y = 0;
|
||||
player_state_0->last_move_time_s = SDL_GetTicks() / 1000.0;
|
||||
player_state_1->x = 4 * RECTS_PER_WINDOW / 5;
|
||||
player_state_1->y = RECTS_PER_WINDOW / 2;
|
||||
player_state_1->speed_x = 0;
|
||||
player_state_1->speed_y = 0;
|
||||
player_state_1->last_move_time_s = player_state_0->last_move_time_s;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
SDL_Event event;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Window *window;
|
||||
double current_time_s;
|
||||
double move_delay = MOVE_DELAY_NORMAL;
|
||||
PlayerState player_state_0, player_state_1;
|
||||
unsigned int current_time, last_time;
|
||||
|
||||
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
|
||||
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window, &renderer);
|
||||
SDL_SetWindowTitle(window, "asdw: move red | jkli: move blue | space: move faster | esc: restart");
|
||||
|
||||
main_loop:
|
||||
init_state(&player_state_0, &player_state_1, &move_delay);
|
||||
while (1) {
|
||||
current_time = SDL_GetTicks();
|
||||
current_time_s = current_time / 1000.0;
|
||||
while (SDL_PollEvent(&event) == 1) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
goto quit;
|
||||
} else if (event.type == SDL_KEYDOWN) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
goto main_loop;
|
||||
|
||||
case SDLK_SPACE:
|
||||
move_delay = MOVE_DELAY_FAST;
|
||||
break;
|
||||
|
||||
case SDLK_a:
|
||||
player_state_0.speed_x = -1;
|
||||
break;
|
||||
case SDLK_d:
|
||||
player_state_0.speed_x = 1;
|
||||
break;
|
||||
case SDLK_w:
|
||||
player_state_0.speed_y = -1;
|
||||
break;
|
||||
case SDLK_s:
|
||||
player_state_0.speed_y = 1;
|
||||
break;
|
||||
|
||||
case SDLK_j:
|
||||
player_state_1.speed_x = -1;
|
||||
break;
|
||||
case SDLK_l:
|
||||
player_state_1.speed_x = 1;
|
||||
break;
|
||||
case SDLK_i:
|
||||
player_state_1.speed_y = -1;
|
||||
break;
|
||||
case SDLK_k:
|
||||
player_state_1.speed_y = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (event.type == SDL_KEYUP) {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_SPACE:
|
||||
move_delay = MOVE_DELAY_NORMAL;
|
||||
break;
|
||||
|
||||
case SDLK_a:
|
||||
case SDLK_d:
|
||||
player_state_0.speed_x = 0;
|
||||
break;
|
||||
case SDLK_w:
|
||||
case SDLK_s:
|
||||
player_state_0.speed_y = 0;
|
||||
break;
|
||||
|
||||
case SDLK_j:
|
||||
case SDLK_l:
|
||||
player_state_1.speed_x = 0;
|
||||
break;
|
||||
case SDLK_i:
|
||||
case SDLK_k:
|
||||
player_state_1.speed_y = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current_time != last_time) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
draw_player(
|
||||
renderer,
|
||||
&player_state_0,
|
||||
current_time_s,
|
||||
move_delay,
|
||||
255,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
draw_player(
|
||||
renderer,
|
||||
&player_state_1,
|
||||
current_time_s,
|
||||
move_delay,
|
||||
0,
|
||||
0,
|
||||
255
|
||||
);
|
||||
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
last_time = current_time;
|
||||
}
|
||||
quit:
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user