rewrite progress
rahh
This commit is contained in:
parent
1b1cf7e940
commit
636dabd8b1
21
.vscode/c_cpp_properties.json
vendored
Normal file
21
.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.22000.0",
|
||||
"compilerPath": "C:/mingw64/bin/gcc.exe",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "windows-gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
55
.vscode/settings.json
vendored
Normal file
55
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"pthread.h": "c",
|
||||
"fumotris.h": "c",
|
||||
"string.h": "c",
|
||||
"input.h": "c",
|
||||
"stdint.h": "c",
|
||||
"iso646.h": "c",
|
||||
"win.h": "c",
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"string_view": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"execution": "cpp"
|
||||
}
|
||||
}
|
1
checksums.txt
Normal file
1
checksums.txt
Normal file
|
@ -0,0 +1 @@
|
|||
{"source\\main.c": "3d2369e9333b52142cb9f019e877e434", "source\\io\\controller.c": "4459cc302f4b70b072f39b43e87a0c08", "source\\io\\input.c": "d3336a096a3ac2d792292d84dd20fb8f", "source\\io\\platforms\\win.c": "4eb14343a9cb40a7f6a9d9e43329c46e", "source\\io\\platforms\\winio.c": "b3a5e9d8f2e8ab4ec38d14007e4fc3f4"}
|
BIN
objects/controller.o
Normal file
BIN
objects/controller.o
Normal file
Binary file not shown.
BIN
objects/input.o
Normal file
BIN
objects/input.o
Normal file
Binary file not shown.
BIN
objects/main.o
Normal file
BIN
objects/main.o
Normal file
Binary file not shown.
BIN
objects/win.o
Normal file
BIN
objects/win.o
Normal file
Binary file not shown.
94
run.py
Normal file
94
run.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
import os, sys
|
||||
import json, hashlib
|
||||
|
||||
|
||||
def walk_source(path):
|
||||
source_paths = []
|
||||
subdirs = []
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
source_paths += [os.path.join(dirpath, f) for f in filenames if f.endswith(".c")]
|
||||
subdirs.append(dirpath)
|
||||
|
||||
return (source_paths, subdirs)
|
||||
|
||||
|
||||
def get_checksums(source_files):
|
||||
checksums = {}
|
||||
|
||||
for path in source_files:
|
||||
with open(path, "rb") as source_file:
|
||||
source = source_file.read()
|
||||
|
||||
checksum = hashlib.md5(source).hexdigest()
|
||||
checksums[path] = checksum
|
||||
|
||||
return checksums
|
||||
|
||||
|
||||
def read_checksum_file():
|
||||
checksums = {}
|
||||
|
||||
if not os.path.exists("checksums.txt"):
|
||||
return checksums
|
||||
|
||||
with open("checksums.txt", "rb") as checksum_file:
|
||||
checksums = json.loads(checksum_file.read())
|
||||
|
||||
return checksums
|
||||
|
||||
|
||||
def write_checksum_file(checksums):
|
||||
with open("checksums.txt", "w+") as checksum_file:
|
||||
checksum_file.write(json.dumps(checksums))
|
||||
|
||||
|
||||
def get_object_names(path):
|
||||
object_names = []
|
||||
|
||||
for file in os.listdir(path):
|
||||
if os.path.isfile(os.path.join(path, file)):
|
||||
name = os.path.splitext(os.path.basename(file))[0]
|
||||
|
||||
object_names.append(name)
|
||||
|
||||
return object_names
|
||||
|
||||
|
||||
def build(source_path, obj_path, out_path, recompile = False):
|
||||
source_paths, subdirs = walk_source(source_path)
|
||||
|
||||
if recompile:
|
||||
result = os.system(f"gcc {' '.join(source_paths)} -I {' -I '.join(subdirs)} -o {out_path} -pthread -Wall -std=c17 -pedantic")
|
||||
print(result)
|
||||
return
|
||||
|
||||
|
||||
checksums_before = read_checksum_file()
|
||||
checksums_now = get_checksums(source_paths)
|
||||
|
||||
object_names = get_object_names(obj_path)
|
||||
compile_list = []
|
||||
|
||||
for path in checksums_now:
|
||||
name = os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
if path not in checksums_before or checksums_before[path] != checksums_now[path] or name not in object_names:
|
||||
compile_list.append(path)
|
||||
|
||||
if name in object_names:
|
||||
object_names.remove(name)
|
||||
|
||||
for object_name in object_names:
|
||||
os.remove(f"{obj_path}\\{object_name}.o")
|
||||
|
||||
for path in compile_list:
|
||||
name = os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
os.system(f"gcc -c {path} -I {' -I '.join(subdirs)} -o {obj_path}\\{name}.o -pthread -Wall -std=c17 -pedantic")
|
||||
|
||||
write_checksum_file(checksums_now)
|
||||
print(os.system(f"gcc {obj_path}\\*.o -o {out_path} -pthread -Wall -std=c17 -pedantic"))
|
||||
|
||||
|
||||
build(sys.argv[1], sys.argv[2], sys.argv[3], True)
|
17
source/fumotris.h
Normal file
17
source/fumotris.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define nullptr ((void*)0)
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint_fast8_t u8f;
|
||||
|
||||
typedef uint16_t u16;
|
||||
typedef uint_fast16_t u16f;
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint_fast32_t u32f;
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint_fast64_t u64f;
|
||||
|
21
source/game/gametime.c
Normal file
21
source/game/gametime.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win.h"
|
||||
#endif
|
||||
|
||||
double GetTime()
|
||||
{
|
||||
struct timespec ts;
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
|
||||
return ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
|
||||
}
|
||||
|
||||
bool Wait(double seconds)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return WindowsWait(seconds);
|
||||
#endif
|
||||
}
|
6
source/game/gametime.h
Normal file
6
source/game/gametime.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
double GetTime();
|
||||
|
||||
bool Wait(double seconds);
|
79
source/game/tetr.c
Normal file
79
source/game/tetr.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
#include "term.h"
|
||||
|
||||
struct TetrMap {
|
||||
size_t wid;
|
||||
size_t hgt;
|
||||
size_t area;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
u8 rot;
|
||||
|
||||
u8 *blks;
|
||||
};
|
||||
|
||||
struct TetrMap NewTetrMap(size_t wid, size_t hgt)
|
||||
{
|
||||
return (struct TetrMap) {
|
||||
wid, hgt, wid * hgt,
|
||||
0, 0, 0,
|
||||
};
|
||||
}
|
||||
|
||||
void TetrMapToTermBuf(struct TetrMap *map, struct TermBuf *term)
|
||||
{
|
||||
static const u8f blk_colors[8] = { 8, 14, 11, 13, 10, 9, 12, 3 };
|
||||
|
||||
for (size_t y = 0; y < map->hgt; y++) {
|
||||
for (size_t x = 0; x < map->wid; x++) {
|
||||
size_t map_i = y * map->wid + x;
|
||||
size_t buf_i = (y + map->y) * term->wid + (x + map->x) * 2;
|
||||
|
||||
struct CharBlk4 *a = &term->blks[buf_i];
|
||||
struct CharBlk4 *b = &term->blks[buf_i + 1];
|
||||
|
||||
if (map->blks[map_i] == 0) {
|
||||
a->ch = '(';
|
||||
b->ch = ')';
|
||||
} else {
|
||||
a->ch = '[';
|
||||
b->ch = ']';
|
||||
}
|
||||
|
||||
u8 fg = blk_colors[map->blks[map_i]];
|
||||
a->fg = fg;
|
||||
b->fg = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TetrCollisionCheck(struct TetrMap *board, struct TetrMap *piece, int dx, int dy)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (size_t y = piece->y + dy; y < piece->y + piece->hgt + dy; y++) {
|
||||
for (size_t x = piece->x + dx; x < piece->x + piece->wid + dx; x++) {
|
||||
if(piece->blks[i] == 0)
|
||||
goto next;
|
||||
|
||||
if(y >= board->hgt or x >= board->wid)
|
||||
return false;
|
||||
|
||||
size_t board_i = y * board->wid + x;
|
||||
if(board->blks[board_i] != 0)
|
||||
return false;
|
||||
|
||||
next:
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
28
source/game/tetr.h
Normal file
28
source/game/tetr.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
#include "term.h"
|
||||
|
||||
struct TetrMap {
|
||||
size_t wid;
|
||||
size_t hgt;
|
||||
size_t area;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
u8 rot;
|
||||
|
||||
u8 *blks;
|
||||
};
|
||||
|
||||
struct TetrMap NewTetrMap(size_t wid, size_t hgt);
|
||||
|
||||
void TetrMapToTermBuf(struct TetrMap *map, struct TermBuf *term);
|
||||
|
||||
bool TetrCollisionCheck(struct TetrMap *board, struct TetrMap *piece, int dx, int dy);
|
265
source/io/ctrl.c
Normal file
265
source/io/ctrl.c
Normal file
|
@ -0,0 +1,265 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
|
||||
#define IO_BUF_SIZE 8
|
||||
|
||||
enum InputType {
|
||||
KEY,
|
||||
AXIS,
|
||||
JOYSTICK,
|
||||
WINDOW,
|
||||
ESCAPE
|
||||
};
|
||||
|
||||
struct InputRecord {
|
||||
enum InputType type;
|
||||
u16 id;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u32 value;
|
||||
bool is_down;
|
||||
} axis;
|
||||
struct {
|
||||
u32 x;
|
||||
u32 y;
|
||||
} joystick;
|
||||
} data;
|
||||
|
||||
double timestamp;
|
||||
};
|
||||
|
||||
struct InputResult {
|
||||
size_t count;
|
||||
struct InputRecord buf[IO_BUF_SIZE];
|
||||
};
|
||||
|
||||
struct Axis {
|
||||
union {
|
||||
struct {
|
||||
u32 value;
|
||||
bool is_down;
|
||||
} axis;
|
||||
struct {
|
||||
u32 x;
|
||||
u32 y;
|
||||
} joystick;
|
||||
} data;
|
||||
|
||||
double last_pressed;
|
||||
double last_released;
|
||||
};
|
||||
|
||||
enum KeyCode {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
SOFT_DROP,
|
||||
HARD_DROP,
|
||||
ROTATE_CCW,
|
||||
ROTATE_CW,
|
||||
ROTATE_180,
|
||||
SWAP,
|
||||
ESC
|
||||
};
|
||||
|
||||
enum AxisCode {
|
||||
VSCROLL,
|
||||
HSCROLL
|
||||
};
|
||||
|
||||
enum JoystickCode {
|
||||
MOUSE
|
||||
};
|
||||
|
||||
typedef u32 hashtype;
|
||||
hashtype Hash(void *item, size_t size)
|
||||
{
|
||||
u8* data = (u8*)item;
|
||||
|
||||
u32 h = 98317;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
h ^= data[i];
|
||||
h *= 0x5bd1e995;
|
||||
h ^= h >> 15;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
struct ident {
|
||||
u16 id;
|
||||
enum InputType type;
|
||||
};
|
||||
|
||||
hashtype hash_ident(u16f id, enum InputType type)
|
||||
{
|
||||
struct ident obj = { id, type };
|
||||
return Hash(&obj, sizeof(struct ident));
|
||||
}
|
||||
|
||||
struct ctrl_bkt {
|
||||
hashtype bind_hash;
|
||||
size_t index;
|
||||
hashtype code_hash;
|
||||
|
||||
struct Axis axis;
|
||||
};
|
||||
|
||||
struct Ctrl {
|
||||
size_t capacity;
|
||||
size_t filled;
|
||||
struct ctrl_bkt *bkts;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
typedef struct Ctrl Ctrl;
|
||||
|
||||
Ctrl NewCtrl(struct ctrl_bkt *bkts_prealloc, size_t capacity)
|
||||
{
|
||||
Ctrl ctrl;
|
||||
ctrl.capacity = capacity;
|
||||
ctrl.filled = 0;
|
||||
memset(bkts_prealloc, 0, sizeof(struct ctrl_bkt) * capacity);
|
||||
ctrl.bkts = bkts_prealloc;
|
||||
ctrl.mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
struct ctrl_bkt *get_bkt(Ctrl *ctrl, size_t i)
|
||||
{
|
||||
return &ctrl->bkts[i];
|
||||
}
|
||||
|
||||
struct ctrl_bkt *find_bind(Ctrl *ctrl, hashtype bind_hash, hashtype search)
|
||||
{
|
||||
size_t i = bind_hash % ctrl->capacity;
|
||||
|
||||
struct ctrl_bkt *next;
|
||||
for (size_t offset = 0; offset < ctrl->capacity; offset++) {
|
||||
i = (i + 1) % ctrl->capacity;
|
||||
|
||||
next = get_bkt(ctrl, i);
|
||||
if (next->bind_hash != search)
|
||||
continue;
|
||||
|
||||
return next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct ctrl_bkt *find_code(Ctrl *ctrl, size_t *i, hashtype search)
|
||||
{
|
||||
struct ctrl_bkt *next;
|
||||
for (size_t offset = 0; offset < ctrl->capacity; offset++) {
|
||||
*i = (*i + 1) % ctrl->capacity;
|
||||
|
||||
next = get_bkt(ctrl, *i);
|
||||
if (next->code_hash != search)
|
||||
continue;
|
||||
|
||||
return next;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CtrlMap(Ctrl *ctrl, u16f bind, u16f code, enum InputType type)
|
||||
{
|
||||
if (ctrl->filled == ctrl->capacity)
|
||||
return false;
|
||||
|
||||
hashtype bind_hash = hash_ident(bind, type);
|
||||
struct ctrl_bkt *bind_bkt = find_bind(ctrl, bind_hash, 0);
|
||||
bind_bkt->bind_hash = bind_hash;
|
||||
|
||||
hashtype code_hash = hash_ident(code, type);
|
||||
size_t code_i = code_hash % ctrl->capacity;
|
||||
struct ctrl_bkt *code_bkt = find_code(ctrl, &code_i, 0);
|
||||
code_bkt->code_hash = code_hash;
|
||||
|
||||
bind_bkt->index = code_i;
|
||||
ctrl->filled += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Axis *find_bind_axis(Ctrl *ctrl, u16f bind, enum InputType type)
|
||||
{
|
||||
hashtype bind_hash = hash_ident(bind, KEY);
|
||||
struct ctrl_bkt *bind_bkt = find_bind(ctrl, bind_hash, bind_hash);
|
||||
if (bind_bkt == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return &get_bkt(ctrl, bind_bkt->index)->axis;
|
||||
}
|
||||
|
||||
struct Axis *CtrlGet(Ctrl *ctrl, u16f code, enum InputType type)
|
||||
{
|
||||
hashtype code_hash = hash_ident(code, type);
|
||||
size_t code_i = code_hash % ctrl->capacity;
|
||||
struct ctrl_bkt *code_bkt = find_code(ctrl, &code_i, code_hash);
|
||||
if (code_bkt == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return &code_bkt->axis;
|
||||
}
|
||||
|
||||
bool CtrlUpdateKey(Ctrl *ctrl, struct InputRecord *record)
|
||||
{
|
||||
struct Axis *axis = find_bind_axis(ctrl, record->id, KEY);
|
||||
if (axis == nullptr)
|
||||
return false;
|
||||
|
||||
if (record->data.axis.is_down) {
|
||||
axis->last_pressed = record->timestamp;
|
||||
} else {
|
||||
axis->last_released = record->timestamp;
|
||||
}
|
||||
axis->data.axis.is_down = record->data.axis.is_down;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CtrlUpdateAxis(Ctrl *ctrl, struct InputRecord *record)
|
||||
{
|
||||
struct Axis *axis = find_bind_axis(ctrl, record->id, AXIS);
|
||||
if (axis == nullptr)
|
||||
return false;
|
||||
|
||||
axis->data.axis.value = record->data.axis.value;
|
||||
axis->last_pressed = record->timestamp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CtrlUpdateJoystick(Ctrl *ctrl, struct InputRecord *record)
|
||||
{
|
||||
struct Axis *axis = find_bind_axis(ctrl, record->id, JOYSTICK);
|
||||
if (axis == nullptr)
|
||||
return false;
|
||||
|
||||
axis->data.joystick.x = record->data.joystick.x;
|
||||
axis->data.joystick.y = record->data.joystick.y;
|
||||
axis->last_pressed = record->timestamp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CtrlUpdateWindow(Ctrl *ctrl, struct InputRecord *record)
|
||||
{
|
||||
struct Axis *axis = find_bind_axis(ctrl, record->id, WINDOW);
|
||||
if (axis == nullptr)
|
||||
return false;
|
||||
|
||||
axis->data.joystick.x = record->data.joystick.x;
|
||||
axis->data.joystick.y = record->data.joystick.y;
|
||||
axis->last_pressed = record->timestamp;
|
||||
|
||||
return true;
|
||||
}
|
114
source/io/ctrl.h
Normal file
114
source/io/ctrl.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
|
||||
#define IO_BUF_SIZE 8
|
||||
|
||||
enum InputType {
|
||||
KEY,
|
||||
AXIS,
|
||||
JOYSTICK,
|
||||
WINDOW,
|
||||
ESCAPE
|
||||
};
|
||||
|
||||
struct InputRecord {
|
||||
enum InputType type;
|
||||
u16 id;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u32 value;
|
||||
bool is_down;
|
||||
} axis;
|
||||
struct {
|
||||
u32 x;
|
||||
u32 y;
|
||||
} joystick;
|
||||
} data;
|
||||
|
||||
double timestamp;
|
||||
};
|
||||
|
||||
struct InputResult {
|
||||
size_t count;
|
||||
struct InputRecord buf[IO_BUF_SIZE];
|
||||
};
|
||||
|
||||
struct Axis {
|
||||
union {
|
||||
struct {
|
||||
u32 value;
|
||||
bool is_down;
|
||||
} axis;
|
||||
struct {
|
||||
u32 x;
|
||||
u32 y;
|
||||
} joystick;
|
||||
} data;
|
||||
|
||||
double last_pressed;
|
||||
double last_released;
|
||||
};
|
||||
|
||||
enum KeyCode {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
SOFT_DROP,
|
||||
HARD_DROP,
|
||||
ROTATE_CCW,
|
||||
ROTATE_CW,
|
||||
ROTATE_180,
|
||||
SWAP,
|
||||
ESC
|
||||
};
|
||||
|
||||
enum AxisCode {
|
||||
VSCROLL,
|
||||
HSCROLL
|
||||
};
|
||||
|
||||
enum JoystickCode {
|
||||
MOUSE
|
||||
};
|
||||
|
||||
typedef u32 hashtype;
|
||||
|
||||
struct ctrl_bkt {
|
||||
hashtype bind_hash;
|
||||
size_t index;
|
||||
hashtype code_hash;
|
||||
|
||||
struct Axis axis;
|
||||
};
|
||||
|
||||
struct Ctrl {
|
||||
size_t capacity;
|
||||
size_t filled;
|
||||
struct ctrl_bkt *bkts;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
typedef struct Ctrl Ctrl;
|
||||
|
||||
Ctrl NewCtrl(struct ctrl_bkt *bkts_prealloc, size_t capacity);
|
||||
|
||||
bool CtrlMap(Ctrl *ctrl, u16f bind, u16f code, enum InputType type);
|
||||
|
||||
struct Axis *CtrlGet(Ctrl *ctrl, u16f code, enum InputType type);
|
||||
|
||||
bool CtrlUpdateKey(Ctrl *ctrl, struct InputRecord *record);
|
||||
|
||||
bool CtrlUpdateAxis(Ctrl *ctrl, struct InputRecord *record);
|
||||
|
||||
bool CtrlUpdateJoystick(Ctrl *ctrl, struct InputRecord *record);
|
||||
|
||||
bool CtrlUpdateWindow(Ctrl *ctrl, struct InputRecord *record);
|
||||
|
79
source/io/input.c
Normal file
79
source/io/input.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ctrl.h"
|
||||
#include "fumotris.h"
|
||||
#include "gametime.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win.h"
|
||||
#endif
|
||||
|
||||
bool dispatch(Ctrl *ctrl, struct InputRecord *record)
|
||||
{
|
||||
switch (record->type) {
|
||||
case KEY:
|
||||
return CtrlUpdateKey(ctrl, record);
|
||||
case AXIS:
|
||||
return CtrlUpdateAxis(ctrl, record);
|
||||
case JOYSTICK:
|
||||
return CtrlUpdateJoystick(ctrl, record);
|
||||
case WINDOW:
|
||||
return CtrlUpdateWindow(ctrl, record);
|
||||
case ESCAPE:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool write_result(Ctrl *ctrl, struct InputResult *result)
|
||||
{
|
||||
double now = GetTime();
|
||||
pthread_mutex_lock(&ctrl->mutex);
|
||||
|
||||
for (size_t i = 0; i < result->count; i++) {
|
||||
if (result->buf[i].type == ESCAPE)
|
||||
return false;
|
||||
result->buf[i].timestamp = now;
|
||||
|
||||
dispatch(ctrl, &result->buf[i]);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ctrl->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
void *block_input(void *args)
|
||||
{
|
||||
Ctrl *ctrl = args;
|
||||
struct InputResult result;
|
||||
|
||||
input_loop:
|
||||
bool success;
|
||||
#ifdef _WIN32
|
||||
success = WindowsBlockInput(&result);
|
||||
#endif
|
||||
|
||||
if (!success) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!write_result(ctrl, &result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
goto input_loop;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void StartInput(Ctrl *ctrl)
|
||||
{
|
||||
pthread_t input_thread;
|
||||
pthread_create(&input_thread, nullptr, block_input, ctrl);
|
||||
//pthread_join(input_thread, nullptr);
|
||||
}
|
11
source/io/input.h
Normal file
11
source/io/input.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ctrl.h"
|
||||
#include "fumotris.h"
|
||||
|
||||
void StartInput(Ctrl *ctrl);
|
32
source/io/platforms/win.c
Normal file
32
source/io/platforms/win.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "winhandler.h"
|
||||
|
||||
bool WindowsInit()
|
||||
{
|
||||
if (!WinInitInputHandle())
|
||||
return false;
|
||||
|
||||
if (!WinInitTimer())
|
||||
return false;
|
||||
|
||||
if(!WinInitConsole())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowsBlockInput(struct InputResult *result)
|
||||
{
|
||||
return WinBlockInput(result);
|
||||
}
|
||||
|
||||
bool WindowsWait(double seconds)
|
||||
{
|
||||
return WinWait(seconds);
|
||||
}
|
14
source/io/platforms/win.h
Normal file
14
source/io/platforms/win.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "input.h"
|
||||
|
||||
bool WindowsInit();
|
||||
|
||||
bool WindowsBlockInput(struct InputResult *result);
|
||||
|
||||
bool WindowsWait(double seconds);
|
140
source/io/platforms/winhandler.c
Normal file
140
source/io/platforms/winhandler.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
#include "input.h"
|
||||
|
||||
struct Windows {
|
||||
HANDLE input_handle;
|
||||
HANDLE timer;
|
||||
};
|
||||
static struct Windows windows;
|
||||
|
||||
bool WinInitInputHandle()
|
||||
{
|
||||
windows.input_handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (windows.input_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinInitTimer()
|
||||
{
|
||||
windows.timer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
if (!windows.timer)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinInitConsole()
|
||||
{
|
||||
DWORD mode = ENABLE_EXTENDED_FLAGS
|
||||
| ENABLE_PROCESSED_INPUT
|
||||
| ENABLE_MOUSE_INPUT
|
||||
| ENABLE_WINDOW_INPUT
|
||||
| ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
return SetConsoleMode(windows.input_handle, mode);
|
||||
}
|
||||
|
||||
void set_key_record(struct InputRecord *record, KEY_EVENT_RECORD win_key)
|
||||
{
|
||||
record->type = KEY;
|
||||
record->id = win_key.wVirtualKeyCode;
|
||||
record->data.axis.is_down = win_key.bKeyDown;
|
||||
|
||||
if (win_key.wVirtualKeyCode == VK_ESCAPE)
|
||||
record->type = ESCAPE;
|
||||
}
|
||||
|
||||
bool set_mouse_record(struct InputRecord *record, MOUSE_EVENT_RECORD win_mouse)
|
||||
{
|
||||
switch (win_mouse.dwEventFlags) {
|
||||
case MOUSE_WHEELED:
|
||||
record->type = AXIS;
|
||||
record->id = 0;
|
||||
record->data.axis.value = win_mouse.dwButtonState;
|
||||
break;
|
||||
case MOUSE_HWHEELED:
|
||||
record->type = AXIS;
|
||||
record->id = 1;
|
||||
record->data.axis.value = win_mouse.dwButtonState;
|
||||
break;
|
||||
case MOUSE_MOVED:
|
||||
record->type = JOYSTICK;
|
||||
record->id = 0;
|
||||
record->data.joystick.x = win_mouse.dwMousePosition.X;
|
||||
record->data.joystick.y = win_mouse.dwMousePosition.Y;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_window_record(struct InputRecord *record, WINDOW_BUFFER_SIZE_RECORD win_resize)
|
||||
{
|
||||
record->type = WINDOW;
|
||||
record->data.joystick.x = win_resize.dwSize.X;
|
||||
record->data.joystick.y = win_resize.dwSize.Y;
|
||||
}
|
||||
|
||||
bool dispatch_record(struct InputRecord *record, INPUT_RECORD win_record)
|
||||
{
|
||||
switch (win_record.EventType) {
|
||||
case KEY_EVENT:
|
||||
set_key_record(record, win_record.Event.KeyEvent);
|
||||
return true;
|
||||
case MOUSE_EVENT:
|
||||
return set_mouse_record(record, win_record.Event.MouseEvent);
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
set_window_record(record, win_record.Event.WindowBufferSizeEvent);
|
||||
return true;
|
||||
default:
|
||||
record->type = ESCAPE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinBlockInput(struct InputResult *result)
|
||||
{
|
||||
INPUT_RECORD buf[8];
|
||||
DWORD count;
|
||||
|
||||
if (!ReadConsoleInput(windows.input_handle, buf, 8, &count))
|
||||
return false;
|
||||
|
||||
size_t unused_offset = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
struct InputRecord record;
|
||||
|
||||
bool include = dispatch_record(&record, buf[i]);
|
||||
if (record.type == ESCAPE)
|
||||
return false;
|
||||
if (!include)
|
||||
unused_offset += 1;
|
||||
|
||||
result->buf[i - unused_offset] = record;
|
||||
}
|
||||
result->count = count - unused_offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinWait(double seconds)
|
||||
{
|
||||
LARGE_INTEGER duration;
|
||||
duration.QuadPart = (u64)(-10000000.0 * seconds);
|
||||
|
||||
if (!SetWaitableTimer(windows.timer, &duration, 0, NULL, NULL, FALSE))
|
||||
return false;
|
||||
|
||||
DWORD result = WaitForSingleObject(windows.timer, INFINITE);
|
||||
if (result != WAIT_OBJECT_0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
18
source/io/platforms/winhandler.h
Normal file
18
source/io/platforms/winhandler.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
|
||||
bool WinInitInputHandle();
|
||||
|
||||
bool WinInitTimer();
|
||||
|
||||
bool WinInitConsole();
|
||||
|
||||
bool WinBlockInput(struct InputResult *result);
|
||||
|
||||
bool WinWait(double seconds);
|
128
source/io/term.c
Normal file
128
source/io/term.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
|
||||
struct CharBlk4 {
|
||||
char ch;
|
||||
u8 bg : 4;
|
||||
u8 fg : 4;
|
||||
};
|
||||
|
||||
struct TermBuf {
|
||||
size_t wid;
|
||||
size_t hgt;
|
||||
size_t area;
|
||||
struct CharBlk4 *blks;
|
||||
};
|
||||
|
||||
struct TermBuf NewTermBuf(size_t wid, size_t hgt)
|
||||
{
|
||||
return (struct TermBuf) {
|
||||
wid, hgt, wid * hgt
|
||||
};
|
||||
}
|
||||
|
||||
size_t TermMaxChars(struct TermBuf *term)
|
||||
{
|
||||
static const size_t max_color_str_len = 10;
|
||||
static const size_t reset_str_len = 7;
|
||||
|
||||
return reset_str_len
|
||||
+ (max_color_str_len + 1) * term->area
|
||||
+ (term->hgt - 1)
|
||||
+ 1;
|
||||
}
|
||||
|
||||
size_t printcol4(char *buf, size_t at, size_t max, u8f col, char ch)
|
||||
{
|
||||
if (col < 8)
|
||||
col += 30;
|
||||
else
|
||||
col += 82;
|
||||
|
||||
return snprintf(buf + at, max - at, "\x1b[%um%c", col, ch);
|
||||
}
|
||||
|
||||
size_t printblk4(char *buf, size_t at, size_t max, struct CharBlk4 *blk)
|
||||
{
|
||||
u8f bg;
|
||||
if (blk->bg < 8)
|
||||
bg = blk->bg + 40;
|
||||
else
|
||||
bg = blk->bg + 92;
|
||||
|
||||
u8f fg;
|
||||
if (blk->fg < 8)
|
||||
fg = blk->fg + 30;
|
||||
else
|
||||
fg = blk->fg + 82;
|
||||
|
||||
return snprintf(buf + at, max - at, "\x1b[%u;%um%c", bg, fg, blk->ch);
|
||||
}
|
||||
|
||||
size_t TermBufToChars(struct TermBuf *term, char *buf, size_t max_chars)
|
||||
{
|
||||
u8f last_bg = 0;
|
||||
u8f last_fg = 0;
|
||||
|
||||
size_t filled = snprintf(buf, max_chars, "\x1b[H\x1b[0m");
|
||||
|
||||
for(size_t y = 0; y < term->hgt; y++) {
|
||||
for(size_t x = 0; x < term->wid; x++) {
|
||||
size_t i = y * term->wid + x;
|
||||
struct CharBlk4 *blk = &term->blks[i];
|
||||
|
||||
// DEBUG
|
||||
if (blk->ch == 0)
|
||||
blk->ch = '#';
|
||||
// DEBUG
|
||||
|
||||
if (blk->bg != 0 and blk->bg != last_bg) {
|
||||
last_bg = blk->bg;
|
||||
if (blk->fg != 0 and blk->fg != last_fg) {
|
||||
filled += printblk4(buf, filled, max_chars, blk);
|
||||
last_fg = blk->fg;
|
||||
} else {
|
||||
filled += printcol4(buf, filled, max_chars, blk->bg, blk->ch);
|
||||
}
|
||||
} else if (blk->fg != 0 and blk->fg != last_fg) {
|
||||
filled += printcol4(buf, filled, max_chars, blk->fg, blk->ch);
|
||||
last_fg = blk->fg;
|
||||
} else {
|
||||
buf[filled] = blk->ch;
|
||||
filled += 1;
|
||||
}
|
||||
}
|
||||
buf[filled] = '\n';
|
||||
filled += 1;
|
||||
}
|
||||
buf[filled] = 0;
|
||||
return filled;
|
||||
}
|
||||
|
||||
/*int main()
|
||||
{
|
||||
struct TermBuf term;
|
||||
term.wid = 20;
|
||||
term.hgt = 10;
|
||||
term.area = 20 * 10;
|
||||
struct CharBlk4 blks[term.area];
|
||||
memset(&blks, 0, sizeof(struct CharBlk4) * term.area);
|
||||
term.blks = blks;
|
||||
|
||||
size_t out_max = TermMaxChars(&term);
|
||||
char out[out_max];
|
||||
memset(out, 0, out_max);
|
||||
|
||||
TermBufToChars(&term, out, out_max);
|
||||
|
||||
puts(out);
|
||||
|
||||
return 0;
|
||||
}*/
|
29
source/io/term.h
Normal file
29
source/io/term.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fumotris.h"
|
||||
|
||||
struct CharBlk4 {
|
||||
char ch;
|
||||
u8 bg : 4;
|
||||
u8 fg : 4;
|
||||
};
|
||||
|
||||
struct TermBuf {
|
||||
size_t wid;
|
||||
size_t hgt;
|
||||
size_t area;
|
||||
struct CharBlk4 *blks;
|
||||
};
|
||||
|
||||
struct TermBuf NewTermBuf(size_t wid, size_t hgt);
|
||||
|
||||
size_t TermMaxChars(struct TermBuf *term);
|
||||
|
||||
size_t TermBufToChars(struct TermBuf *term, char *buf, size_t max_chars);
|
136
source/main.c
Normal file
136
source/main.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include <iso646.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "control.h"
|
||||
#include "fumotris.h"
|
||||
#include "term.h"
|
||||
#include "tetr.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win.h"
|
||||
#endif
|
||||
|
||||
const enum KeyCode key_codes[] = {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
SOFT_DROP,
|
||||
HARD_DROP,
|
||||
ROTATE_CCW,
|
||||
ROTATE_CW,
|
||||
ROTATE_180,
|
||||
SWAP,
|
||||
ESC
|
||||
};
|
||||
const u16f key_binds[] = {
|
||||
0x25,
|
||||
0x27,
|
||||
0x28,
|
||||
0x20,
|
||||
'Z',
|
||||
'X',
|
||||
'A',
|
||||
'C',
|
||||
0x1B
|
||||
};
|
||||
|
||||
const enum AxisCode axis_codes[] = {
|
||||
VSCROLL,
|
||||
HSCROLL
|
||||
};
|
||||
const u16f axis_binds[] = { 0, 1 };
|
||||
|
||||
u8 I[16] = {
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
1, 1, 1, 1,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
void Loop(Ctrl *ctrl)
|
||||
{
|
||||
struct TermBuf term = NewTermBuf(20, 20);
|
||||
struct CharBlk4 term_blks[term.area];
|
||||
memset(term_blks, 0, sizeof(struct CharBlk4) * term.area);
|
||||
term.blks = term_blks;
|
||||
|
||||
size_t out_max = TermMaxChars(&term);
|
||||
char out[out_max];
|
||||
memset(out, 0, out_max);
|
||||
|
||||
struct TetrMap board = NewTetrMap(10, 20);
|
||||
u8 board_blks[board.area];
|
||||
memset(board_blks, 0, board.area);
|
||||
board.blks = board_blks;
|
||||
|
||||
struct TetrMap falling = NewTetrMap(4, 4);
|
||||
u8 falling_blks[falling.area];
|
||||
memcpy(falling_blks, I, falling.area);
|
||||
falling.blks = falling_blks;
|
||||
|
||||
for (int i = 0; i < 7779997; i++) {
|
||||
TetrMapToTermBuf(&board, &term);
|
||||
TetrMapToTermBuf(&falling, &term);
|
||||
|
||||
size_t size = TermBufToChars(&term, out, out_max);
|
||||
//puts(out);
|
||||
puts("\x1b[H");
|
||||
|
||||
//falling.y += 1;
|
||||
|
||||
for(int j = 0; j < ctrl->capacity; j++) {
|
||||
printf("val:%u, is_down:%u, x:%u, y:%u, press:%f, relse:%f\n",
|
||||
ctrl->bkts[j].axis.data.axis.value, ctrl->bkts[j].axis.data.axis.is_down,
|
||||
ctrl->bkts[j].axis.data.joystick.x, ctrl->bkts[j].axis.data.joystick.y,
|
||||
ctrl->bkts[j].axis.last_pressed, ctrl->bkts[j].axis.last_released);
|
||||
}
|
||||
/*
|
||||
struct Axis *axis = CtrlGet(ctrl, LEFT, KEY);
|
||||
struct Axis *right = CtrlGet(ctrl, RIGHT, KEY);
|
||||
|
||||
printf("ctrl:%u\n", axis);
|
||||
printf("ctrl:%u\n", right);
|
||||
|
||||
printf("%f\n", axis->last_pressed);
|
||||
|
||||
if (axis->data.axis.is_down) {
|
||||
printf("left");
|
||||
falling.x -= 1;
|
||||
}
|
||||
|
||||
if (right->data.axis.is_down) {
|
||||
printf("right");
|
||||
falling.x += 1;
|
||||
}*/
|
||||
|
||||
WindowsWait(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
WindowsInit();
|
||||
|
||||
struct ctrl_bkt bkts[16];
|
||||
Ctrl ctrl = NewCtrl(bkts, 16);
|
||||
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
CtrlMap(&ctrl, key_binds[i], key_codes[i], KEY);
|
||||
}
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
CtrlMap(&ctrl, axis_codes[i], axis_binds[i], AXIS);
|
||||
}
|
||||
CtrlMap(&ctrl, 0, MOUSE, JOYSTICK);
|
||||
CtrlMap(&ctrl, 0, 0, WINDOW);
|
||||
|
||||
printf("set controls\n");
|
||||
|
||||
StartInput(&ctrl);
|
||||
Loop(&ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
422
source/test.cpp
Normal file
422
source/test.cpp
Normal file
|
@ -0,0 +1,422 @@
|
|||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
using namespace std;
|
||||
|
||||
void gotoxy(int x, int y);
|
||||
void setcolor(WORD color);
|
||||
void setForeGroundAndBackGroundColor(int ForeGroundColor,int BackGroundColor);
|
||||
void clearscreen();
|
||||
void drawpixel( unsigned char x, unsigned char y, unsigned char Color);
|
||||
void drawpixel2( unsigned char x, unsigned char y, unsigned char Color, char character);
|
||||
void drawcircle(int x, int y, int a, int b, int color);
|
||||
void drawline(int x0, int y0, int x1, int y1, int color);
|
||||
void drawfilledrectangle(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char bkcol);
|
||||
void drawframe(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,char text_[]);
|
||||
void drawwindow(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,unsigned char bkcol,char text_[]);
|
||||
|
||||
int main()
|
||||
{
|
||||
gotoxy(1,23);
|
||||
setcolor(7);
|
||||
clearscreen();
|
||||
|
||||
cout<<"click anywhere in console window to write - hello world -\n\n\n\n\n\n\n\n\n\n\n\n\n"
|
||||
"Press Ctrl+C to Exit";
|
||||
|
||||
HANDLE hout= GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
INPUT_RECORD InputRecord;
|
||||
DWORD Events;
|
||||
COORD coord;
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
cci.dwSize = 25;
|
||||
cci.bVisible = FALSE;
|
||||
SetConsoleCursorInfo(hout, &cci);
|
||||
SetConsoleMode(hin, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
|
||||
bool EXITGAME = false;
|
||||
int buttonX=1, buttonY=1;
|
||||
|
||||
drawpixel(buttonX,buttonY ,1);
|
||||
gotoxy(buttonX+2,buttonY);
|
||||
setcolor(3);
|
||||
cout<<"<----- a button \n";
|
||||
|
||||
|
||||
while( !EXITGAME )
|
||||
{
|
||||
|
||||
ReadConsoleInput(hin, &InputRecord, 1, &Events);
|
||||
|
||||
|
||||
switch ( InputRecord.EventType ){
|
||||
case KEY_EVENT: // keyboard input
|
||||
|
||||
|
||||
switch (InputRecord.Event.KeyEvent.wVirtualKeyCode)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
EXITGAME = TRUE;
|
||||
break;
|
||||
|
||||
case VK_SPACE:
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case VK_RETURN:
|
||||
|
||||
break;
|
||||
|
||||
case VK_LEFT:
|
||||
// left key move player left
|
||||
cout<<"VK_LEFT = "<<InputRecord.Event.KeyEvent.wVirtualKeyCode <<" \n";
|
||||
|
||||
break;
|
||||
|
||||
case VK_RIGHT:
|
||||
// right key move player right
|
||||
cout<<"VK_RIGHT = "<<InputRecord.Event.KeyEvent.wVirtualKeyCode <<" \n";
|
||||
|
||||
break;
|
||||
|
||||
case VK_UP:
|
||||
// up key move player up
|
||||
cout<<"VK_UP = "<<InputRecord.Event.KeyEvent.wVirtualKeyCode <<" \n";
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case VK_DOWN:
|
||||
// up key move player down
|
||||
cout<<"VK_DOWN = "<<InputRecord.Event.KeyEvent.wVirtualKeyCode <<" \n";
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}//switch
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
break;
|
||||
|
||||
case MOUSE_EVENT: // mouse input
|
||||
|
||||
if(InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
|
||||
{
|
||||
coord.X = InputRecord.Event.MouseEvent.dwMousePosition.X;
|
||||
coord.Y = InputRecord.Event.MouseEvent.dwMousePosition.Y;
|
||||
SetConsoleCursorPosition(hout,coord);
|
||||
SetConsoleTextAttribute(hout,rand() %7+9);
|
||||
|
||||
if ( (InputRecord.Event.MouseEvent.dwMousePosition.X == buttonX ) &&
|
||||
( InputRecord.Event.MouseEvent.dwMousePosition.Y == buttonY) ){
|
||||
|
||||
clearscreen();
|
||||
gotoxy(1,1);
|
||||
setcolor(7);
|
||||
drawpixel(buttonX,buttonY ,1);
|
||||
setcolor(3);
|
||||
cout<<" mybutton was pressed \n";
|
||||
setcolor(7);
|
||||
Sleep(500);
|
||||
drawpixel(buttonX,buttonY ,1);
|
||||
gotoxy(buttonX+2,buttonY);
|
||||
setcolor(3);
|
||||
cout<<"<----- a button \n";
|
||||
|
||||
|
||||
}
|
||||
|
||||
cout<<"Hello world at "<< InputRecord.Event.MouseEvent.dwMousePosition.X <<" x "<< InputRecord.Event.MouseEvent.dwMousePosition.Y<<" ";
|
||||
|
||||
}// mouse
|
||||
|
||||
break;
|
||||
|
||||
case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing
|
||||
;
|
||||
break;
|
||||
|
||||
case FOCUS_EVENT: // disregard focus events
|
||||
|
||||
case MENU_EVENT: // disregard menu events
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
cout<<"Unknown event type \n";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FlushConsoleInputBuffer(hin);
|
||||
}
|
||||
gotoxy(1,23);
|
||||
setcolor(7);
|
||||
clearscreen();
|
||||
cout<<"\n";
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gotoxy(int x, int y){
|
||||
COORD coord;
|
||||
coord.X = x; coord.Y = y;
|
||||
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
return;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void setcolor(WORD color){
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
|
||||
return;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//
|
||||
// colors:
|
||||
// 0 = Black
|
||||
// 1 = Blue
|
||||
// 2 = Green
|
||||
// 3 = Cyan
|
||||
// 4 = Red
|
||||
// 5 = Magenta
|
||||
// 6 = Yellow
|
||||
// 7 = LightGray
|
||||
// 8 = DarkGray
|
||||
// 9 = LightBlue
|
||||
// 10 = LightGreen
|
||||
// 11 = LightCyan
|
||||
// 12 = LightRed
|
||||
// 13 = LightMagenta
|
||||
// 14 = LightYellow
|
||||
// 15 = White
|
||||
|
||||
|
||||
//
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void setForeGroundAndBackGroundColor(int ForeGroundColor,int BackGroundColor){
|
||||
int color=16*BackGroundColor+ForeGroundColor;
|
||||
setcolor(color);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void clearscreen(){
|
||||
COORD coordScreen = { 0, 0 };
|
||||
DWORD cCharsWritten;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
DWORD dwConSize;
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
|
||||
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
|
||||
SetConsoleCursorPosition(hConsole, coordScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void drawpixel( unsigned char x, unsigned char y, unsigned char Color){
|
||||
setcolor(Color);
|
||||
gotoxy(x,y);printf("Û");
|
||||
}
|
||||
//*****************************************************************************
|
||||
|
||||
void drawpixel2( unsigned char x, unsigned char y, unsigned char Color, char character){
|
||||
setcolor(Color);
|
||||
gotoxy(x,y);printf("%c",character);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void drawcircle(int x, int y, int a, int b, int color){
|
||||
int wx, wy;
|
||||
int thresh;
|
||||
int asq = a * a;
|
||||
int bsq = b * b;
|
||||
int xa, ya;
|
||||
|
||||
drawpixel(x, y+b, color);
|
||||
drawpixel(x, y-b, color);
|
||||
|
||||
wx = 0;
|
||||
wy = b;
|
||||
xa = 0;
|
||||
ya = asq * 2 * b;
|
||||
thresh = asq / 4 - asq * b;
|
||||
|
||||
for (;;) {
|
||||
thresh += xa + bsq;
|
||||
|
||||
if (thresh >= 0) {
|
||||
ya -= asq * 2;
|
||||
thresh -= ya;
|
||||
wy--;
|
||||
}
|
||||
|
||||
xa += bsq * 2;
|
||||
wx++;
|
||||
|
||||
if (xa >= ya)
|
||||
break;
|
||||
|
||||
|
||||
drawpixel(x+wx, y-wy, color);
|
||||
drawpixel(x-wx, y-wy, color);
|
||||
drawpixel(x+wx, y+wy, color);
|
||||
drawpixel(x-wx, y+wy, color);
|
||||
}
|
||||
|
||||
drawpixel(x+a, y, color);
|
||||
drawpixel(x-a, y, color);
|
||||
|
||||
wx = a;
|
||||
wy = 0;
|
||||
xa = bsq * 2 * a;
|
||||
|
||||
ya = 0;
|
||||
thresh = bsq / 4 - bsq * a;
|
||||
|
||||
for (;;) {
|
||||
thresh += ya + asq;
|
||||
|
||||
if (thresh >= 0) {
|
||||
xa -= bsq * 2;
|
||||
thresh = thresh - xa;
|
||||
wx--;
|
||||
}
|
||||
|
||||
ya += asq * 2;
|
||||
wy++;
|
||||
|
||||
if (ya > xa)
|
||||
break;
|
||||
|
||||
drawpixel(x+wx, y-wy, color);
|
||||
drawpixel(x-wx, y-wy, color);
|
||||
drawpixel(x+wx, y+wy, color);
|
||||
drawpixel(x-wx, y+wy, color);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void drawline(int x0, int y0, int x1, int y1, int color){
|
||||
int pix = color;
|
||||
int dy = y1 - y0;
|
||||
int dx = x1 - x0;
|
||||
int stepx, stepy;
|
||||
|
||||
if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
|
||||
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
|
||||
dy <<= 1; // dy is now 2*dy
|
||||
dx <<= 1; // dx is now 2*dx
|
||||
|
||||
drawpixel( x0, y0,pix);
|
||||
if (dx > dy) {
|
||||
int fraction = dy - (dx >> 1); // same as 2*dy - dx
|
||||
while (x0 != x1) {
|
||||
if (fraction >= 0) {
|
||||
y0 += stepy;
|
||||
fraction -= dx; // same as fraction -= 2*dx
|
||||
}
|
||||
x0 += stepx;
|
||||
fraction += dy; // same as fraction -= 2*dy
|
||||
drawpixel( x0, y0,pix);
|
||||
}
|
||||
} else {
|
||||
int fraction = dx - (dy >> 1);
|
||||
while (y0 != y1) {
|
||||
if (fraction >= 0) {
|
||||
x0 += stepx;
|
||||
fraction -= dy;
|
||||
}
|
||||
y0 += stepy;
|
||||
fraction += dx;
|
||||
drawpixel( x0, y0,pix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
void drawframe(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,char text_[]){
|
||||
unsigned i,j,m;{
|
||||
|
||||
m=(sx-x); //differential
|
||||
j=m/8; //adjust
|
||||
j=j-1; //more adjustment
|
||||
gotoxy(x,y);printf("É"); //Top left corner of drawframe
|
||||
gotoxy(sx,y);printf("»"); //Top right corner of drawframe
|
||||
gotoxy(x,sy);printf("È"); //Bottom left corner of drawframe
|
||||
gotoxy(sx,sy);printf("¼"); //Bottom right corner of drawframe
|
||||
|
||||
for (i=x+1;i<sx;i++){
|
||||
gotoxy(i,y);printf("Í"); // Top horizontol line
|
||||
gotoxy(i,sy);printf("Í"); // Bottom Horizontal line
|
||||
}
|
||||
|
||||
for (i=y+1;i<sy;i++){
|
||||
gotoxy(x,i);printf("º"); //Left Vertical line
|
||||
gotoxy(sx,i);printf("º"); //Right Vertical Line
|
||||
}
|
||||
|
||||
gotoxy(x+j,y);printf(text_); //put Title
|
||||
gotoxy(1,24);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void drawfilledrectangle(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char bkcol){
|
||||
int x,y;
|
||||
setcolor(bkcol); //Set to color bkcol
|
||||
|
||||
for (y=y1;y<y2;y++){ //Fill Y Region Loop
|
||||
for (x=x1;x<x2;x++) { //Fill X region Loop
|
||||
gotoxy(x,y);printf(" "); //Draw Solid space
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
void drawwindow(unsigned x,unsigned y,unsigned sx,unsigned sy,
|
||||
unsigned char col, unsigned char col2,unsigned char bkcol,char text_[]){
|
||||
drawfilledrectangle(x,y,sx,sy,bkcol);
|
||||
drawframe(x,y,sx,sy,col,col2,text_);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
void drawcolorpalette(){
|
||||
for (int i=0;i<16;i++){
|
||||
for (int j=0;j<16;j++){
|
||||
setForeGroundAndBackGroundColor(i,j);
|
||||
gotoxy(i*4,j);printf("%d",(i*j)+1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
Loading…
Reference in a new issue