Compare commits

...

5 Commits

12 changed files with 204 additions and 26 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,3 +1,3 @@
add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c")
add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c" "src/touch.c")
target_include_directories(camera PUBLIC "inc" PRIVATE "privinc")
target_link_libraries(camera PUBLIC container mouse pad terrain util PRIVATE gfx)

View File

@ -35,6 +35,7 @@ extern struct sprite cursor_sprite;
void camera_update_pad(struct camera *cam, const struct pad *p);
void camera_update_mouse(struct camera *cam, const struct mouse *m);
bool camera_update_touch(struct camera *cam, const struct mouse *m);
bool camera_translate(const struct camera *cam, const struct util_rect *dim, short *x, short *y);
void cursor_init(struct cursor *c);
bool cursor_collision(const struct camera *cam, const struct util_rect *d);

57
src/camera/src/touch.c Normal file
View File

@ -0,0 +1,57 @@
#include <camera.h>
#include <mouse.h>
#include <camera_private.h>
#include <gfx.h>
static void cursor_update(struct cursor *const c, const struct mouse *const m)
{
if (c->screen.last_w != screen_w
|| c->screen.last_h != screen_h)
cursor_init(c);
c->x = m->x;
c->y = m->y;
}
static bool update_speed(struct camera *const cam, const struct mouse *const m)
{
bool ret = false;
int *const sx = &cam->x_speed, *const sy = &cam->y_speed;
if (mouse_pressed(m, MOUSE_BUTTON_LEFT))
{
*sx = m->dx;
*sy = m->dy;
ret = *sx || *sy;
}
else if (*sx || *sy)
{
const int qx = *sx / 4;
if (qx)
*sx -= qx;
else
*sx = 0;
const int qy = *sy / 4;
if (qy)
*sy -= qy;
else
*sy = 0;
}
return ret;
}
bool camera_update_touch(struct camera *const cam, const struct mouse *const m)
{
bool ret;
cursor_update(&cam->cursor, m);
ret = update_speed(cam, m);
camera_update_pos(cam);
return ret;
}

View File

@ -26,7 +26,7 @@ int game(void)
{
const struct human_player_cfg cfg =
{
.sel_periph = HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE,
.sel_periph = HUMAN_PLAYER_PERIPH_TOUCH,
.padn = i,
.pl =
{
@ -86,8 +86,7 @@ int game(void)
terrain_update(&map);
if (terrain_render(&map, &h->cam)
|| human_player_render(h, &o)
|| cursor_render(&h->cam.cursor))
|| human_player_render(h, &o))
goto end;
/* TODO: render AI players. */

View File

@ -16,12 +16,13 @@ enum mouse_button
struct mouse
{
short x, y;
short x, y, dx, dy;
int mask, oldmask;
};
void mouse_init(struct mouse *m);
void mouse_update(struct mouse *m);
bool mouse_pressed(const struct mouse *m, enum mouse_button b);
bool mouse_justpressed(const struct mouse *m, enum mouse_button b);
bool mouse_justreleased(const struct mouse *m, enum mouse_button b);

View File

@ -39,6 +39,7 @@ static void mouse_event(const SDL_MouseMotionEvent *const ev,
void mouse_update(struct mouse *const m)
{
const short x = m->x, y = m->y;
SDL_Event ev;
int n;
@ -71,6 +72,9 @@ void mouse_update(struct mouse *const m)
}
}
m->dx = m->x - x;
m->dy = m->y - y;
end:
if (n < 0)

View File

@ -1,6 +1,11 @@
#include <mouse.h>
#include <stdbool.h>
bool mouse_pressed(const struct mouse *const m, const enum mouse_button b)
{
return m->mask & (1 << b);
}
bool mouse_justpressed(const struct mouse *const m,
const enum mouse_button b)
{

View File

@ -22,6 +22,7 @@ struct human_player_cfg
enum human_player_periph
{
HUMAN_PLAYER_PERIPH_PAD,
HUMAN_PLAYER_PERIPH_TOUCH,
HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE
} sel_periph;
@ -39,10 +40,12 @@ struct human_player
{
struct pad pad;
struct
struct human_player_kbm
{
struct mouse mouse;
struct keyboard keyboard;
bool long_press, pan;
unsigned int lp_t;
} kbm;
} periph;

View File

@ -207,15 +207,33 @@ static bool select_resources(struct human_player *const h, const short x,
}
static bool select_instances(struct human_player *const h,
const struct player_others *const o, const bool excl)
const struct player_others *const o, const bool excl,
const bool same_type)
{
unsigned long x, y;
cursor_pos(&h->cam, &x, &y);
return select_buildings(h, x, y, excl)
|| select_units(h, x, y, excl)
|| select_resources(h, x, y, o, excl);
if (!same_type || !h->n_sel)
return select_buildings(h, x, y, excl)
|| select_units(h, x, y, excl)
|| select_resources(h, x, y, o, excl);
else
{
switch (h->sel->type)
{
case INSTANCE_TYPE_UNIT:
return select_units(h, x, y, excl);
case INSTANCE_TYPE_BUILDING:
return select_buildings(h, x, y, excl);
case INSTANCE_TYPE_RESOURCE:
select_resources(h, x, y, o, excl);
}
}
return false;
}
static bool instance_collision(const struct camera *const cam,
@ -518,7 +536,7 @@ static bool update_from_pad(struct human_player *const h,
|| pad_justpressed(p, PAD_KEY_EXIT))
ret = true;
else if (pad_justpressed(p, PAD_KEY_A))
select_instances(h, o, false);
select_instances(h, o, false, false);
else if (pad_justpressed(p, PAD_KEY_B))
move_units(h, o);
else if (pad_justpressed(p, PAD_KEY_C))
@ -529,10 +547,58 @@ static bool update_from_pad(struct human_player *const h,
return ret;
}
static bool update_keyboard_mouse_common(const struct mouse *const m,
const struct keyboard *const k)
{
bool ret = false;
if (keyboard_justpressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_EXIT)))
ret = true;
else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_F11)))
gfx_toggle_fullscreen();
return ret;
}
static bool update_from_touch(struct human_player *const h,
struct player_others *const o)
{
struct mouse *const m = &h->periph.kbm.mouse;
struct keyboard *const k = &h->periph.kbm.keyboard;
mouse_update(m);
keyboard_update(k);
struct human_player_kbm *const kbm = &h->periph.kbm;
if (mouse_pressed(m, MOUSE_BUTTON_LEFT) && !kbm->pan)
{
enum {LONG_PRESS_THRESHOLD = 30};
if (kbm->lp_t < LONG_PRESS_THRESHOLD)
kbm->lp_t++;
else if (!kbm->long_press)
{
kbm->long_press = true;
deselect_instances(h);
}
}
else if (mouse_justreleased(m, MOUSE_BUTTON_LEFT))
{
if (!kbm->pan && !select_instances(h, o, false, true))
move_units(h, o);
kbm->pan = false;
kbm->long_press = false;
kbm->lp_t = 0;
}
return update_keyboard_mouse_common(m, k);
}
static bool update_from_keyboard_mouse(struct human_player *const h,
struct player_others *const o)
{
bool ret = false;
struct mouse *const m = &h->periph.kbm.mouse;
struct keyboard *const k = &h->periph.kbm.keyboard;
@ -545,17 +611,13 @@ static bool update_from_keyboard_mouse(struct human_player *const h,
keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT))
|| keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT));
if (!select_instances(h, o, !shift_pressed))
if (!select_instances(h, o, !shift_pressed, false))
deselect_instances(h);
}
else if (mouse_justreleased(m, MOUSE_BUTTON_RIGHT))
move_units(h, o);
else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_EXIT)))
ret = true;
else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_F11)))
gfx_toggle_fullscreen();
return ret;
return update_keyboard_mouse_common(m, k);
}
bool human_player_update(struct human_player *const h,
@ -577,6 +639,15 @@ bool human_player_update(struct human_player *const h,
camera_update_pad(&h->cam, &h->periph.pad);
break;
case HUMAN_PLAYER_PERIPH_TOUCH:
{
struct human_player_kbm *const kbm = &h->periph.kbm;
ret = update_from_touch(h, o);
kbm->pan |= camera_update_touch(&h->cam, &kbm->mouse);
}
break;
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
ret = update_from_keyboard_mouse(h, o);
camera_update_mouse(&h->cam, &h->periph.kbm.mouse);
@ -659,6 +730,21 @@ int human_player_render(const struct human_player *const h,
|| gui_render(h))
return -1;
switch (h->sel_periph)
{
case HUMAN_PLAYER_PERIPH_PAD:
/* Fall through. */
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
cursor_render(&h->cam.cursor);
break;
case HUMAN_PLAYER_PERIPH_TOUCH:
break;
default:
return -1;
}
return 0;
}
@ -672,6 +758,8 @@ int human_player_init(const struct human_player_cfg *const cfg,
switch (h->sel_periph = cfg->sel_periph)
{
case HUMAN_PLAYER_PERIPH_TOUCH:
/* Fall through. */
case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE:
mouse_init(&h->periph.kbm.mouse);
keyboard_init(&h->periph.kbm.keyboard);

View File

@ -54,7 +54,7 @@ instance_hp resource_maxhp(const struct resource *const res)
static const instance_hp hp[] =
{
[RESOURCE_TYPE_GOLD] = 1000,
[RESOURCE_TYPE_WOOD] = 45,
[RESOURCE_TYPE_WOOD] = 45
};
return hp[res->type];
@ -73,12 +73,31 @@ int resource_render(const struct resource *const res,
if (sprite_clone(&resource_sprites[res->type], s))
return -1;
if (res->type == RESOURCE_TYPE_GOLD)
{
s->h = in->r.h;
const struct instance_render_off *off = NULL;
if (res->res.gold.n_miners)
s->v += s->h;
switch (res->type)
{
case RESOURCE_TYPE_GOLD:
s->h = in->r.h;
if (res->res.gold.n_miners)
s->v += s->h;
break;
case RESOURCE_TYPE_WOOD:
{
static const struct instance_render_off w_off =
{
.y = -30
};
off = &w_off;
}
break;
default:
break;
}
const struct instance_render_cfg cfg =
@ -88,7 +107,8 @@ int resource_render(const struct resource *const res,
.prim = {.s = s},
.cam = cam,
.sel = sel,
.max_hp = resource_maxhp(res)
.max_hp = resource_maxhp(res),
.off = off
};
return instance_render(&cfg);
@ -103,7 +123,7 @@ static void get_dimensions(const enum resource_type type, short *const w,
} dim[] =
{
[RESOURCE_TYPE_GOLD] = {.w = 96, .h = 96},
[RESOURCE_TYPE_WOOD] = {.w = 32, .h = 46}
[RESOURCE_TYPE_WOOD] = {.w = 32, .h = 16}
};
const struct dim *const d = &dim[type];