diff options
| -rwxr-xr-x | build.sh | 3 | ||||
| -rw-r--r-- | main.c | 102 | ||||
| -rw-r--r-- | platform.c | 100 | 
3 files changed, 115 insertions, 90 deletions
| @@ -1,3 +1,4 @@ -gcc -Wall -pedantic -O0 -c main.c -o main.o && \ +flags=-Wall -pedantic -O0  +gcc $flags -O0 -c main.c -o main.o && \  gcc main.o -lSDL2 -o main && \  ./main @@ -1,12 +1,9 @@  #include <assert.h>  #include <stdio.h>  #include <stdlib.h> -#include <SDL2/SDL.h> +#include "platform.c" -#define WINDOW_W 1280 -#define WINDOW_H 720 - -void editMask(float *mask, float x, float y, float color, float size) { +void PaintMask(float *mask, float x, float y, float color, float size) {  	for (int j = y - size / 2; j < y + size / 2; j++) {  		for (int i = x - size / 2; i < x + size / 2; i++) {  			if (i > 0 && i < WINDOW_W && j > 0 && j < WINDOW_H) { @@ -17,59 +14,12 @@ void editMask(float *mask, float x, float y, float color, float size) {  	}  } -SDL_Texture *createTiledTexture(SDL_Renderer *context, const char *filename) { -	SDL_Surface *texture_surface = SDL_LoadBMP(filename); -	SDL_Texture *texture_tile = SDL_CreateTextureFromSurface(context, texture_surface); -	int tile_w = texture_surface->w; -	int tile_h = texture_surface->h; -	SDL_FreeSurface(texture_surface); - -	SDL_Texture *texture = SDL_CreateTexture(context, -			SDL_PIXELFORMAT_RGBA8888, -			SDL_TEXTUREACCESS_TARGET, -			WINDOW_W, WINDOW_H); -	SDL_SetRenderTarget(context, texture); -	for (int y = 0; y < WINDOW_H; y += tile_h) { -		for (int x = 0; x < WINDOW_W; x += tile_w) { -			SDL_Rect tile_rect = { x, y, tile_w, tile_h }; -			SDL_RenderCopy(context, texture_tile, 0, &tile_rect); -		} -	} -	SDL_DestroyTexture(texture_tile); -	SDL_SetRenderTarget(context, 0); -	return texture; -} - -int main() { -	SDL_Init(SDL_INIT_VIDEO); - -	SDL_Window *window = SDL_CreateWindow("Cannons", -			SDL_WINDOWPOS_UNDEFINED, -			SDL_WINDOWPOS_UNDEFINED, -			WINDOW_W, -			WINDOW_H, -			0); - -	SDL_Renderer *context = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - -	SDL_Texture *background = createTiledTexture(context, "background.bmp"); - -	SDL_Texture *foreground = createTiledTexture(context, "foreground.bmp"); -	SDL_SetTextureBlendMode(foreground, SDL_BLENDMODE_MOD); - -	SDL_Texture *terrain = SDL_CreateTexture(context, -			SDL_PIXELFORMAT_RGBA8888, -			SDL_TEXTUREACCESS_TARGET, -			WINDOW_W, WINDOW_H); -	SDL_SetTextureBlendMode(terrain, SDL_BLENDMODE_BLEND); - +void GameMain() {  	// Terrain generation  	float *mask = calloc(WINDOW_W * WINDOW_H, sizeof(float)); -	for (int i = 500 * WINDOW_W; i < WINDOW_W * WINDOW_H; i++) { +	for (int i = 0; i < 100 * WINDOW_W; i++) {  		mask[i] = 1.0;  	} -	SDL_Surface *mask_surface = SDL_CreateRGBSurfaceWithFormat(0, -			WINDOW_W, WINDOW_H, 32, SDL_PIXELFORMAT_RGBA8888);  	// Player variables  	float player_x = 100; @@ -83,7 +33,7 @@ int main() {  	// Event handling  	int exit = 0;  	while (!exit) { -		SDL_Event event = {0}; +		SDL_Event event;  		while (SDL_PollEvent(&event)) {  			if (event.type == SDL_QUIT) {  				exit = 1; @@ -93,39 +43,18 @@ int main() {  		Uint32 mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y);  		float size = 100;  		if (mouse_state & SDL_BUTTON_LMASK) { -			editMask(mask, mouse_x, mouse_y, 1.0, size); +			PaintMask(mask, mouse_x, WINDOW_H - mouse_y, 1.0, size);  		} else if (mouse_state & SDL_BUTTON_RMASK) { -			editMask(mask, mouse_x, mouse_y, 0.0, size); -		} - -		// Main loop -		SDL_SetRenderDrawColor(context, 40, 40, 40, 255); -		SDL_RenderClear(context); - -		SDL_RenderCopy(context, background, 0, 0); - -		SDL_LockSurface(mask_surface); -		for (int i = 0; i < mask_surface->w * mask_surface->h; i++) { -			((Uint32 *)mask_surface->pixels)[i] = mask[i] ? 0xffffffff : 0x00000000; +			PaintMask(mask, mouse_x, WINDOW_H - mouse_y, 0.0, size);  		} -		SDL_UnlockSurface(mask_surface); -		SDL_Texture *mask_texture = SDL_CreateTextureFromSurface(context, mask_surface); -		SDL_SetRenderTarget(context, terrain); -		SDL_SetRenderDrawColor(context, 0, 0, 0, 0); -		SDL_RenderClear(context); -		SDL_RenderCopy(context, mask_texture, 0, 0); -		SDL_RenderCopy(context, foreground, 0, 0); -		SDL_SetRenderTarget(context, 0); -		SDL_RenderCopy(context, terrain, 0, 0); -		SDL_DestroyTexture(mask_texture);  		// Time delta calculation -		double new_t = (double) SDL_GetTicks64() / 1000.0; +		double new_t = GetCurrentTimestamp();  		double dt = new_t - old_t;  		old_t = new_t;  		// Player logic -		if (mask[(int)player_x + (WINDOW_H - (int)player_y) * WINDOW_W] == 0.0) { +		if (mask[(int)player_x + (int)player_y * WINDOW_W] == 0.0) {  			player_y += player_vy * dt;  			player_vy += player_ay * dt;  		} else { @@ -133,17 +62,12 @@ int main() {  			player_vy = 0;  		} -		// Draw player -		SDL_SetRenderDrawColor(context, 255, 0, 0, 255); -		SDL_Rect player_rect = {player_x - 5, WINDOW_H - player_y - 10, 10, 10 }; -		SDL_RenderFillRect(context, &player_rect); - -		SDL_RenderPresent(context); +		RenderScene(mask, player_x, player_y);  		SDL_Delay(1);  	} +} -	SDL_DestroyRenderer(context); -	SDL_DestroyWindow(window); -	SDL_Quit(); +int main() { +	PlatformMain(GameMain);  	return 0;  } diff --git a/platform.c b/platform.c new file mode 100644 index 0000000..7ba6d53 --- /dev/null +++ b/platform.c @@ -0,0 +1,100 @@ +#include <SDL2/SDL.h> + +#define WINDOW_W 1280 +#define WINDOW_H 720 + +SDL_Renderer *context = 0; +SDL_Texture *background = 0; +SDL_Texture *foreground = 0; +SDL_Texture *terrain = 0; +SDL_Texture *mask_texture = 0; + +double GetCurrentTimestamp() { +	return (double) SDL_GetTicks64() / 1000.0; +} + +SDL_Texture *createTiledTexture(SDL_Renderer *context, const char *filename, int width, int height) { +	SDL_Surface *texture_surface = SDL_LoadBMP(filename); +	SDL_Texture *texture_tile = SDL_CreateTextureFromSurface(context, texture_surface); +	int tile_w = texture_surface->w; +	int tile_h = texture_surface->h; +	SDL_FreeSurface(texture_surface); + +	SDL_Texture *texture = SDL_CreateTexture(context, +			SDL_PIXELFORMAT_RGBA8888, +			SDL_TEXTUREACCESS_TARGET, +			width, height); +	SDL_SetRenderTarget(context, texture); +	for (int y = 0; y < height; y += tile_h) { +		for (int x = 0; x < width; x += tile_w) { +			SDL_Rect tile_rect = { x, y, tile_w, tile_h }; +			SDL_RenderCopy(context, texture_tile, 0, &tile_rect); +		} +	} +	SDL_DestroyTexture(texture_tile); +	SDL_SetRenderTarget(context, 0); +	return texture; +} + +void PlatformMain(void (*GameMain)(void)) { +	SDL_Init(SDL_INIT_VIDEO); + +	SDL_Window *window = SDL_CreateWindow("Cannons", +			SDL_WINDOWPOS_UNDEFINED, +			SDL_WINDOWPOS_UNDEFINED, +			WINDOW_W, +			WINDOW_H, +			0); + +	context = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + +	background = createTiledTexture(context, "background.bmp", WINDOW_W, WINDOW_H); + +	foreground = createTiledTexture(context, "foreground.bmp", WINDOW_W, WINDOW_H); +	SDL_SetTextureBlendMode(foreground, SDL_BLENDMODE_MOD); + +	terrain = SDL_CreateTexture(context, +			SDL_PIXELFORMAT_RGBA8888, +			SDL_TEXTUREACCESS_TARGET, +			WINDOW_W, WINDOW_H); +	SDL_SetTextureBlendMode(terrain, SDL_BLENDMODE_BLEND); + +	mask_texture = SDL_CreateTexture(context, +			SDL_PIXELFORMAT_RGBA8888, +			SDL_TEXTUREACCESS_STREAMING, +			WINDOW_W, WINDOW_H); + +	GameMain(); + +	SDL_DestroyRenderer(context); +	SDL_DestroyWindow(window); +	SDL_Quit(); +} + +void RenderScene(float *mask, int player_x, int player_y) { +	void *pixels; +	int pitch; +	SDL_LockTexture(mask_texture, 0, &pixels, &pitch); +	Uint32 *p = (Uint32 *) pixels; +	for (int j = 0; j < WINDOW_H; j++) { +		for (int i = 0; i < WINDOW_W; i++) { +			p[i + j * WINDOW_W] = mask[i + (WINDOW_H - j) * WINDOW_W] ? 0xffffffff : 0x00000000; +		} +	} +	SDL_UnlockTexture(mask_texture); + +	SDL_SetRenderDrawColor(context, 40, 40, 40, 255); +	SDL_RenderClear(context); +	SDL_RenderCopy(context, background, 0, 0); +	SDL_SetRenderTarget(context, terrain); +	SDL_SetRenderDrawColor(context, 0, 0, 0, 0); +	SDL_RenderClear(context); +	SDL_RenderCopy(context, mask_texture, 0, 0); +	SDL_RenderCopy(context, foreground, 0, 0); +	SDL_SetRenderTarget(context, 0); +	SDL_RenderCopy(context, terrain, 0, 0); +	SDL_SetRenderDrawColor(context, 255, 0, 0, 255); +	SDL_Rect player_rect = {player_x - 5, WINDOW_H - player_y - 10, 10, 10 }; +	SDL_RenderFillRect(context, &player_rect); +	SDL_RenderPresent(context); +} | 
