Some basic rendering
This commit is contained in:
@@ -22,7 +22,7 @@ RM := rm -f
|
|||||||
DEBUG ?= 1
|
DEBUG ?= 1
|
||||||
|
|
||||||
COMMON_CFLAGS := -std=$(STD) -Werror -Wextra -Wall -MMD -MP -I$(SRC_DIR) `pkg-config --cflags glib-2.0`
|
COMMON_CFLAGS := -std=$(STD) -Werror -Wextra -Wall -MMD -MP -I$(SRC_DIR) `pkg-config --cflags glib-2.0`
|
||||||
COMMON_LDFLAGS := -std=$(STD) -lm `pkg-config --libs glib-2.0`
|
COMMON_LDFLAGS := -std=$(STD) -lm `pkg-config --libs glib-2.0 sdl3 sdl3-image`
|
||||||
|
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
COMMON_CFLAGS += -g -DDEBUG
|
COMMON_CFLAGS += -g -DDEBUG
|
||||||
@@ -32,8 +32,8 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
CLIENT_CFLAGS := $(COMMON_CFLAGS) `pkg-config --cflags sdl3 sdl3-image`
|
CLIENT_CFLAGS := $(COMMON_CFLAGS) # `pkg-config --cflags sdl3`
|
||||||
CLIENT_LDFLAGS := $(COMMON_LDFLAGS) `pkg-config --libs sdl3 sdl3-image`
|
CLIENT_LDFLAGS := $(COMMON_LDFLAGS) # `pkg-config --libs sdl3`
|
||||||
|
|
||||||
SERVER_CFLAGS := $(COMMON_CFLAGS)
|
SERVER_CFLAGS := $(COMMON_CFLAGS)
|
||||||
SERVER_LDFLAGS := $(COMMON_LDFLAGS)
|
SERVER_LDFLAGS := $(COMMON_LDFLAGS)
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
@@ -31,6 +31,18 @@
|
|||||||
#include <client/gfx_context.h>
|
#include <client/gfx_context.h>
|
||||||
|
|
||||||
static GfxContext *gfx_ctx;
|
static GfxContext *gfx_ctx;
|
||||||
|
static World *test_world;
|
||||||
|
|
||||||
|
World *
|
||||||
|
_make_test_World ()
|
||||||
|
{
|
||||||
|
World *self = World_load_from_file ("res/test_map_2.png");
|
||||||
|
|
||||||
|
/* TODO: add players and so on. That will be in GameState,
|
||||||
|
though. Or GameData. */
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_AppResult
|
SDL_AppResult
|
||||||
SDL_AppInit (void **appstate, int argc, char **argv)
|
SDL_AppInit (void **appstate, int argc, char **argv)
|
||||||
@@ -55,6 +67,8 @@ SDL_AppInit (void **appstate, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gfx_ctx = GfxContext_new ();
|
gfx_ctx = GfxContext_new ();
|
||||||
|
test_world = _make_test_World ();
|
||||||
|
GfxContext_cache_World (gfx_ctx, test_world);
|
||||||
|
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
@@ -78,6 +92,7 @@ SDL_AppIterate (void *appstate)
|
|||||||
UNUSED (appstate);
|
UNUSED (appstate);
|
||||||
|
|
||||||
GfxContext_prerender (gfx_ctx);
|
GfxContext_prerender (gfx_ctx);
|
||||||
|
GfxContext_render_World (gfx_ctx, test_world);
|
||||||
GfxContext_postrender (gfx_ctx);
|
GfxContext_postrender (gfx_ctx);
|
||||||
|
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ GfxContext_new ()
|
|||||||
|
|
||||||
self->renderer = SDL_CreateRenderer (self->window, NULL);
|
self->renderer = SDL_CreateRenderer (self->window, NULL);
|
||||||
|
|
||||||
if (!self->window)
|
if (!self->renderer)
|
||||||
{
|
{
|
||||||
g_critical ("Couldn't create renderer for context %p: %s", self,
|
g_critical ("Couldn't create renderer for context %p: %s", self,
|
||||||
SDL_GetError ());
|
SDL_GetError ());
|
||||||
@@ -48,6 +48,7 @@ GfxContext_new ()
|
|||||||
void
|
void
|
||||||
GfxContext_prerender (GfxContext *self)
|
GfxContext_prerender (GfxContext *self)
|
||||||
{
|
{
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear (self->renderer);
|
SDL_RenderClear (self->renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,3 +65,75 @@ GfxContext_free (GfxContext *self)
|
|||||||
SDL_DestroyWindow (self->window);
|
SDL_DestroyWindow (self->window);
|
||||||
g_free (self);
|
g_free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GfxContext_cache_World (GfxContext *self, World *world)
|
||||||
|
{
|
||||||
|
if (self->world_texture)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture (self->world_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->world_texture = SDL_CreateTexture (self->renderer,
|
||||||
|
SDL_PIXELFORMAT_RGBA32,
|
||||||
|
SDL_TEXTUREACCESS_TARGET,
|
||||||
|
world->width, world->height);
|
||||||
|
|
||||||
|
if (!self->world_texture)
|
||||||
|
{
|
||||||
|
g_error ("Failed to create world texture: %s", SDL_GetError ());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Texture *old_target = SDL_GetRenderTarget (self->renderer);
|
||||||
|
|
||||||
|
SDL_SetRenderTarget (self->renderer, self->world_texture);
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear (self->renderer);
|
||||||
|
|
||||||
|
for (unsigned int y = 0; y < world->height; ++y)
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x < world->width; ++x)
|
||||||
|
{
|
||||||
|
MapTile *mt =
|
||||||
|
g_array_index (world->tiles, MapTile *, y * world->width + x);
|
||||||
|
|
||||||
|
if (!mt)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (mt->terrain_type)
|
||||||
|
{
|
||||||
|
case TERRAIN_WATER:
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 0, 0, 255, 255);
|
||||||
|
break;
|
||||||
|
case TERRAIN_FLAT:
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 0, 255, 0, 255);
|
||||||
|
break;
|
||||||
|
case TERRAIN_HILL:
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 0, 127, 0, 255);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_SetRenderDrawColor (self->renderer, 255, 255, 255, 255);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RenderPoint (self->renderer, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderTarget (self->renderer, old_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GfxContext_render_World (GfxContext *self, World *world)
|
||||||
|
{
|
||||||
|
UNUSED (world);
|
||||||
|
|
||||||
|
if (!self->world_texture)
|
||||||
|
{
|
||||||
|
g_warning ("No world texture present");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FRect dest = { 0, 0, 800, 600 };
|
||||||
|
SDL_RenderTexture (self->renderer, self->world_texture, NULL, &dest);
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ typedef struct GfxContext
|
|||||||
{
|
{
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
|
|
||||||
|
SDL_Texture *world_texture; /* Generated once per every game. */
|
||||||
|
SDL_Texture *player_texture; /* Probably changes every tick. */
|
||||||
|
|
||||||
} GfxContext;
|
} GfxContext;
|
||||||
|
|
||||||
GfxContext *GfxContext_new ();
|
GfxContext *GfxContext_new ();
|
||||||
@@ -38,4 +42,5 @@ void GfxContext_prerender (GfxContext * self);
|
|||||||
void GfxContext_postrender (GfxContext * self);
|
void GfxContext_postrender (GfxContext * self);
|
||||||
void GfxContext_free (GfxContext * self);
|
void GfxContext_free (GfxContext * self);
|
||||||
|
|
||||||
void GfxContext_renderWorld (GfxContext * self, World * world);
|
void GfxContext_cache_World (GfxContext * self, World * world);
|
||||||
|
void GfxContext_render_World (GfxContext * self, World * world);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#include "game_state.h"
|
#include <common/game_state.h>
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* This houses the state of an actual, running game; your player, the
|
|
||||||
other players, the world map, buildings. */
|
|
||||||
|
|
||||||
#include <glib-2.0/glib.h>
|
#include <glib-2.0/glib.h>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include "world.h"
|
#include <common/world.h>
|
||||||
|
|
||||||
typedef struct Player
|
typedef struct Player
|
||||||
{
|
{
|
||||||
@@ -24,5 +21,6 @@ typedef struct GameState
|
|||||||
{
|
{
|
||||||
World *world;
|
World *world;
|
||||||
GArray *players;
|
GArray *players;
|
||||||
Player *me;
|
|
||||||
|
gboolean has_started:1;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|||||||
+91
-1
@@ -1 +1,91 @@
|
|||||||
#include "world.h"
|
#include <common/world.h>
|
||||||
|
|
||||||
|
static inline Uint32
|
||||||
|
_surf_pixel (SDL_Surface *surface, int x, int y)
|
||||||
|
{
|
||||||
|
int bpp = SDL_BYTESPERPIXEL (surface->format);
|
||||||
|
Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
|
||||||
|
|
||||||
|
switch (bpp)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return *p;
|
||||||
|
case 2:
|
||||||
|
return *(Uint16 *) p;
|
||||||
|
case 3:
|
||||||
|
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||||
|
{
|
||||||
|
return p[0] << 16 | p[1] << 8 | p[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return p[0] | p[1] << 8 | p[2] << 16;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
return *(Uint32 *) p;
|
||||||
|
default:
|
||||||
|
return 0; // shouldn't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
World *
|
||||||
|
World_load_from_file (const char *path)
|
||||||
|
{
|
||||||
|
World *self = g_new0 (World, 1);
|
||||||
|
self->buildings = g_array_new (FALSE, FALSE, sizeof (Building *));
|
||||||
|
|
||||||
|
SDL_Surface *surf = IMG_Load (path);
|
||||||
|
|
||||||
|
if (!surf)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to load map from path %s (returning NULL): %s", path,
|
||||||
|
SDL_GetError ());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->width = surf->w;
|
||||||
|
self->height = surf->h;
|
||||||
|
self->tiles =
|
||||||
|
g_array_sized_new (FALSE, FALSE, sizeof (MapTile *), surf->w * surf->h);
|
||||||
|
|
||||||
|
SDL_LockSurface (surf);
|
||||||
|
const SDL_PixelFormatDetails *details =
|
||||||
|
SDL_GetPixelFormatDetails (surf->format);
|
||||||
|
|
||||||
|
for (int y = 0; y < surf->h; ++y)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < surf->w; ++x)
|
||||||
|
{
|
||||||
|
MapTile *mt = g_new0 (MapTile, 1);
|
||||||
|
mt->x = x;
|
||||||
|
mt->y = y;
|
||||||
|
|
||||||
|
Uint32 pixel = _surf_pixel (surf, x, y);
|
||||||
|
Uint8 r, g, b, a;
|
||||||
|
/* NULL is a palette, only used in indexed images. */
|
||||||
|
SDL_GetRGBA (pixel, details, NULL, &r, &g, &b, &a);
|
||||||
|
|
||||||
|
/* The ranges here can be tweaked to work better or
|
||||||
|
worse. */
|
||||||
|
if (b > 196 && r < 50 && g < 50)
|
||||||
|
{
|
||||||
|
mt->terrain_type = TERRAIN_WATER;
|
||||||
|
}
|
||||||
|
else if (g > 200)
|
||||||
|
{
|
||||||
|
mt->terrain_type = TERRAIN_FLAT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mt->terrain_type = TERRAIN_HILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val (self->tiles, mt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_UnlockSurface (surf);
|
||||||
|
SDL_DestroySurface (surf);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|||||||
+7
-6
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3_image/SDL_image.h>
|
||||||
|
|
||||||
#include <glib-2.0/glib.h>
|
#include <glib-2.0/glib.h>
|
||||||
|
|
||||||
typedef enum TerrainType
|
typedef enum TerrainType
|
||||||
@@ -26,15 +29,13 @@ typedef struct World
|
|||||||
GArray *buildings;
|
GArray *buildings;
|
||||||
} World;
|
} World;
|
||||||
|
|
||||||
|
typedef struct Building
|
||||||
typedef struct Building Building; // Typedef is needed to avoid circular dependency
|
|
||||||
struct Building
|
|
||||||
{
|
{
|
||||||
MapTile *parent_tile;
|
MapTile *parent_tile;
|
||||||
unsigned int level;
|
unsigned int level;
|
||||||
|
|
||||||
unsigned int (*at_what_cost) (Building * self, World * world);
|
unsigned int (*at_what_cost) (struct Building * self, World * world);
|
||||||
};
|
} Building;
|
||||||
|
|
||||||
World *World_new (unsigned int width, unsigned int height);
|
World *World_load_from_file (const char *path);
|
||||||
void World_tick (World * self);
|
void World_tick (World * self);
|
||||||
|
|||||||
Reference in New Issue
Block a user