Compare commits
6 Commits
4c425720cc
...
880cf8ab4e
| Author | SHA1 | Date | |
|---|---|---|---|
| 880cf8ab4e | |||
| 1220b36531 | |||
| 2a55252942 | |||
| e8b565508f | |||
| 97829b485c | |||
| a121b8bcdb |
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
zig-out
|
zig-out
|
||||||
.zig-cache
|
.zig-cache
|
||||||
|
*.tiled-session
|
||||||
|
|||||||
22
README.md
@ -1,4 +1,12 @@
|
|||||||
# Game template
|
# Gaem
|
||||||
|
|
||||||
|
* Run & gun
|
||||||
|
* Nuclear throne -esque
|
||||||
|
* Single gun type
|
||||||
|
* Single map
|
||||||
|
* Single enemy type
|
||||||
|
* Collect letters to win, up to 7 letters we have 8 character sprites
|
||||||
|
* The word is WINNER
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
@ -16,15 +24,3 @@ Cross-compile for Windows from Linux:
|
|||||||
```sh
|
```sh
|
||||||
zig build -Dtarget=x86_64-windows
|
zig build -Dtarget=x86_64-windows
|
||||||
```
|
```
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
* Use [Skribidi](https://github.com/memononen/Skribidi) instead of fontstash for text rendering
|
|
||||||
* Support for audio formats (Might not need all of them, haven't decided):
|
|
||||||
* QOA, maybe [qoa.h](https://github.com/phoboslab/qoa/blob/master/qoa.h)?
|
|
||||||
* Flac, maybe [dr_flac.h](https://github.com/mackron/dr_libs/blob/master/dr_flac.h)?
|
|
||||||
* Wav, maybe [dr_wav.h](https://github.com/mackron/dr_libs/blob/master/dr_wav.h)?
|
|
||||||
* Mp3, maybe [dr_mp3.h](https://github.com/mackron/dr_libs/blob/master/dr_mp3.h)?
|
|
||||||
* Gamepad support.
|
|
||||||
* WASM Support. Currently a build config isn't provided for this target.
|
|
||||||
* Update build config for other platforms to reduce binary size. All of the video and audio drivers aren't needed, only gamepads
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ const std = @import("std");
|
|||||||
const sokol = @import("sokol");
|
const sokol = @import("sokol");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const project_name = "game-2026-01-18";
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
@ -105,12 +107,12 @@ pub fn build(b: *std.Build) !void {
|
|||||||
// from here on different handling for native vs wasm builds
|
// from here on different handling for native vs wasm builds
|
||||||
if (target.result.cpu.arch.isWasm()) {
|
if (target.result.cpu.arch.isWasm()) {
|
||||||
try buildWasm(b, .{
|
try buildWasm(b, .{
|
||||||
.name = "sokol_template",
|
.name = project_name,
|
||||||
.mod_main = mod_main,
|
.mod_main = mod_main,
|
||||||
.dep_sokol = dep_sokol,
|
.dep_sokol = dep_sokol,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try buildNative(b, "sokol_template", mod_main, has_console);
|
try buildNative(b, project_name, mod_main, has_console);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,46 @@ const Position = @import("./position.zig");
|
|||||||
|
|
||||||
const Layer = @This();
|
const Layer = @This();
|
||||||
|
|
||||||
|
pub const Bounds = struct {
|
||||||
|
left: i32,
|
||||||
|
right: i32,
|
||||||
|
top: i32,
|
||||||
|
bottom: i32,
|
||||||
|
|
||||||
|
pub const zero = Bounds{
|
||||||
|
.left = 0,
|
||||||
|
.right = 0,
|
||||||
|
.top = 0,
|
||||||
|
.bottom = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn initFromRect(x: i32, y: i32, width: i32, height: i32) Bounds {
|
||||||
|
return Bounds{
|
||||||
|
.left = x,
|
||||||
|
.right = x + width,
|
||||||
|
.top = y,
|
||||||
|
.bottom = y + height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getWidth(self: Bounds) u32 {
|
||||||
|
return @intCast(self.right - self.left + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getHeight(self: Bounds) u32 {
|
||||||
|
return @intCast(self.bottom - self.top + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn combine(lhs: Bounds, rhs: Bounds) Bounds {
|
||||||
|
return Bounds{
|
||||||
|
.left = @min(lhs.left, rhs.left),
|
||||||
|
.right = @max(lhs.right, rhs.right),
|
||||||
|
.top = @min(lhs.top, rhs.top),
|
||||||
|
.bottom = @max(lhs.bottom, rhs.bottom)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const TileVariant = struct {
|
pub const TileVariant = struct {
|
||||||
pub const Chunk = struct {
|
pub const Chunk = struct {
|
||||||
x: i32,
|
x: i32,
|
||||||
@ -15,6 +55,10 @@ pub const TileVariant = struct {
|
|||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
data: []u32,
|
data: []u32,
|
||||||
|
|
||||||
|
pub fn getBounds(self: Chunk) Bounds {
|
||||||
|
return Bounds.initFromRect(self.x, self.y, @intCast(self.width), @intCast(self.height));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Data = union(enum) {
|
pub const Data = union(enum) {
|
||||||
@ -94,7 +138,7 @@ pub const TileVariant = struct {
|
|||||||
try temp_tiles.appendSlice(scratch.allocator(), tiles.items);
|
try temp_tiles.appendSlice(scratch.allocator(), tiles.items);
|
||||||
|
|
||||||
} else if (node.isTag("chunk")) {
|
} else if (node.isTag("chunk")) {
|
||||||
const chunk = try initChunkDataFromXml(scratch.allocator(), scratch, lexer, encoding);
|
const chunk = try initChunkDataFromXml(arena, scratch, lexer, encoding);
|
||||||
try temp_chunks.append(scratch.allocator(), chunk);
|
try temp_chunks.append(scratch.allocator(), chunk);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -105,9 +149,16 @@ pub const TileVariant = struct {
|
|||||||
|
|
||||||
try iter.finish("data");
|
try iter.finish("data");
|
||||||
|
|
||||||
return .{
|
if (temp_chunks.items.len > 0) {
|
||||||
.fixed = try arena.dupe(u32, temp_tiles.items)
|
return .{
|
||||||
};
|
.chunks = try arena.dupe(Chunk, temp_chunks.items)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return .{
|
||||||
|
.fixed = try arena.dupe(u32, temp_tiles.items)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseEncoding(
|
fn parseEncoding(
|
||||||
@ -136,13 +187,46 @@ pub const TileVariant = struct {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getBounds(self: TileVariant) void {
|
pub fn getBounds(self: TileVariant) Bounds {
|
||||||
_ = self; // autofix
|
if (self.data == .fixed) {
|
||||||
|
return Bounds.initFromRect(0, 0, @intCast(self.width), @intCast(self.height));
|
||||||
|
|
||||||
|
} else if (self.data == .chunks) {
|
||||||
|
const chunks = self.data.chunks;
|
||||||
|
|
||||||
|
var result: Bounds = .zero;
|
||||||
|
if (chunks.len > 0) {
|
||||||
|
result = chunks[0].getBounds();
|
||||||
|
for (chunks[1..]) |chunk| {
|
||||||
|
result = result.combine(chunk.getBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(self: TileVariant, x: usize, y: usize) ?u32 {
|
pub fn get(self: TileVariant, x: i32, y: i32) ?u32 {
|
||||||
if ((0 <= x and x < self.width) and (0 <= y and y < self.height)) {
|
if (self.data == .fixed) {
|
||||||
return self.data[y * self.width + x];
|
if ((0 <= x and x < self.width) and (0 <= y and y < self.height)) {
|
||||||
|
const x_u32: u32 = @intCast(x);
|
||||||
|
const y_u32: u32 = @intCast(y);
|
||||||
|
return self.data.fixed[y_u32 * self.width + x_u32];
|
||||||
|
}
|
||||||
|
} else if (self.data == .chunks) {
|
||||||
|
for (self.data.chunks) |chunk| {
|
||||||
|
const ox = x - chunk.x;
|
||||||
|
const oy = y - chunk.y;
|
||||||
|
if ((0 <= ox and ox < chunk.width) and (0 <= oy and oy < chunk.height)) {
|
||||||
|
const ox_u32: u32 = @intCast(ox);
|
||||||
|
const oy_u32: u32 = @intCast(oy);
|
||||||
|
return chunk.data[oy_u32 * chunk.width + ox_u32];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,6 +74,15 @@ pub const List = struct {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getBool(self: List, name: []const u8) ?bool {
|
||||||
|
if (self.get(name)) |value| {
|
||||||
|
if (value == .bool) {
|
||||||
|
return value.bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(name: []const u8, value: Value) Property {
|
pub fn init(name: []const u8, value: Value) Property {
|
||||||
|
|||||||
@ -215,7 +215,18 @@ fn getTilesetByGid(self: *const Tilemap, gid: u32) ?TilesetReference {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTile(self: *const Tilemap, layer: *const Layer, tilesets: Tileset.List, x: usize, y: usize) ?Tile {
|
pub fn getTile(self: *const Tilemap, tilesets: Tileset.List, gid: u32) ?Tile {
|
||||||
|
const tileset_ref = self.getTilesetByGid(gid & GlobalTileId.Flag.clear) orelse return null;
|
||||||
|
const tileset = tilesets.get(tileset_ref.source) orelse return null;
|
||||||
|
const id = gid - tileset_ref.first_gid;
|
||||||
|
|
||||||
|
return Tile{
|
||||||
|
.tileset = tileset,
|
||||||
|
.id = id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getTileByPosition(self: *const Tilemap, layer: *const Layer, tilesets: Tileset.List, x: usize, y: usize) ?Tile {
|
||||||
assert(layer.variant == .tile);
|
assert(layer.variant == .tile);
|
||||||
const tile_variant = layer.variant.tile;
|
const tile_variant = layer.variant.tile;
|
||||||
|
|
||||||
@ -230,6 +241,26 @@ pub fn getTile(self: *const Tilemap, layer: *const Layer, tilesets: Tileset.List
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getTileBounds(self: *const Tilemap) Layer.Bounds {
|
||||||
|
var result: ?Layer.Bounds = null;
|
||||||
|
|
||||||
|
for (self.layers) |layer| {
|
||||||
|
if (layer.variant != .tile) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const layer_bounds = layer.variant.tile.getBounds();
|
||||||
|
if (result == null) {
|
||||||
|
result = layer_bounds;
|
||||||
|
} else {
|
||||||
|
result = layer_bounds.combine(result.?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result orelse .zero;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *const Tilemap) void {
|
pub fn deinit(self: *const Tilemap) void {
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,11 @@ const tiled = @import("tiled");
|
|||||||
|
|
||||||
const Math = @import("./engine/math.zig");
|
const Math = @import("./engine/math.zig");
|
||||||
const Engine = @import("./engine/root.zig");
|
const Engine = @import("./engine/root.zig");
|
||||||
|
const STBImage = @import("stb_image");
|
||||||
const Gfx = Engine.Graphics;
|
const Gfx = Engine.Graphics;
|
||||||
const Audio = Engine.Audio;
|
const Audio = Engine.Audio;
|
||||||
|
const Vec2 = Engine.Vec2;
|
||||||
|
const Rect = Engine.Math.Rect;
|
||||||
|
|
||||||
const Assets = @This();
|
const Assets = @This();
|
||||||
|
|
||||||
@ -17,12 +20,38 @@ const FontName = enum {
|
|||||||
const EnumArray = std.EnumArray(FontName, Gfx.Font.Id);
|
const EnumArray = std.EnumArray(FontName, Gfx.Font.Id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Tilemap = struct {
|
||||||
|
texture: Gfx.TextureId,
|
||||||
|
tile_size: Engine.Vec2,
|
||||||
|
|
||||||
|
|
||||||
|
pub fn getTileUV(self: Tilemap, tile_x: f32, tile_y: f32) Rect {
|
||||||
|
const texture_info = Engine.Graphics.getTextureInfo(self.texture);
|
||||||
|
const tilemap_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.pos = Vec2.init(tile_x, tile_y).multiply(self.tile_size).divide(tilemap_size),
|
||||||
|
.size = self.tile_size.divide(tilemap_size),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
font_id: FontName.EnumArray,
|
font_id: FontName.EnumArray,
|
||||||
wood01: Audio.Data.Id,
|
wood01: Audio.Data.Id,
|
||||||
map: tiled.Tilemap,
|
map: tiled.Tilemap,
|
||||||
tilesets: tiled.Tileset.List,
|
tilesets: tiled.Tileset.List,
|
||||||
|
move_sound: []Audio.Data.Id,
|
||||||
|
|
||||||
|
terrain_tilemap: Tilemap,
|
||||||
|
players_tilemap: Tilemap,
|
||||||
|
weapons_tilemap: Tilemap,
|
||||||
|
|
||||||
pub fn init(gpa: std.mem.Allocator) !Assets {
|
pub fn init(gpa: std.mem.Allocator) !Assets {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||||
|
errdefer arena.deinit();
|
||||||
|
|
||||||
const font_id_array: FontName.EnumArray = .init(.{
|
const font_id_array: FontName.EnumArray = .init(.{
|
||||||
.regular = try Gfx.addFont("regular", @embedFile("assets/roboto-font/Roboto-Regular.ttf")),
|
.regular = try Gfx.addFont("regular", @embedFile("assets/roboto-font/Roboto-Regular.ttf")),
|
||||||
.bold = try Gfx.addFont("bold", @embedFile("assets/roboto-font/Roboto-Bold.ttf")),
|
.bold = try Gfx.addFont("bold", @embedFile("assets/roboto-font/Roboto-Bold.ttf")),
|
||||||
@ -55,17 +84,72 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var tilesets: tiled.Tileset.List = .empty;
|
var tilesets: tiled.Tileset.List = .empty;
|
||||||
try tilesets.add(gpa, "tileset.tsx", tileset);
|
try tilesets.add(gpa, "tilemap.tsx", tileset);
|
||||||
|
|
||||||
|
const players_image = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Players/tilemap_packed.png"));
|
||||||
|
defer players_image.deinit();
|
||||||
|
const players_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = players_image.width,
|
||||||
|
.height = players_image.height,
|
||||||
|
.rgba = players_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const tileset_image = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Tiles/tilemap_packed.png"));
|
||||||
|
defer tileset_image.deinit();
|
||||||
|
const tileset_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = tileset_image.width,
|
||||||
|
.height = tileset_image.height,
|
||||||
|
.rgba = tileset_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const weapons_tileset = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Weapons/tilemap_packed.png"));
|
||||||
|
defer weapons_tileset.deinit();
|
||||||
|
const weapons_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = weapons_tileset.width,
|
||||||
|
.height = weapons_tileset.height,
|
||||||
|
.rgba = weapons_tileset.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const move_c = try Audio.load(.{
|
||||||
|
.data = @embedFile("assets/kenney_desert-shooter-pack_1.0/Sounds/move-c.ogg"),
|
||||||
|
.format = .vorbis,
|
||||||
|
});
|
||||||
|
const move_d = try Audio.load(.{
|
||||||
|
.data = @embedFile("assets/kenney_desert-shooter-pack_1.0/Sounds/move-d.ogg"),
|
||||||
|
.format = .vorbis,
|
||||||
|
});
|
||||||
|
const move_sound = try arena.allocator().dupe(Audio.Data.Id, &.{ move_c, move_d });
|
||||||
|
|
||||||
return Assets{
|
return Assets{
|
||||||
|
.arena = arena,
|
||||||
.font_id = font_id_array,
|
.font_id = font_id_array,
|
||||||
.wood01 = wood01,
|
.wood01 = wood01,
|
||||||
.map = map,
|
.map = map,
|
||||||
.tilesets = tilesets
|
.tilesets = tilesets,
|
||||||
|
.move_sound = move_sound,
|
||||||
|
.terrain_tilemap = .{
|
||||||
|
.texture = tileset_texture,
|
||||||
|
.tile_size = .initFromInt(u32, tileset.tile_width, tileset.tile_height)
|
||||||
|
},
|
||||||
|
.players_tilemap = .{
|
||||||
|
.texture = players_texture,
|
||||||
|
.tile_size = .init(24, 24)
|
||||||
|
},
|
||||||
|
.weapons_tilemap = .{
|
||||||
|
.texture = weapons_texture,
|
||||||
|
.tile_size = .init(24, 24)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Assets, gpa: std.mem.Allocator) void {
|
pub fn deinit(self: *Assets, gpa: std.mem.Allocator) void {
|
||||||
self.map.deinit();
|
self.map.deinit();
|
||||||
self.tilesets.deinit(gpa);
|
self.tilesets.deinit(gpa);
|
||||||
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
"Map/SizeTest": {
|
|
||||||
"height": 4300,
|
|
||||||
"width": 2
|
|
||||||
},
|
|
||||||
"activeFile": "map.tmx",
|
|
||||||
"expandedProjectPaths": [
|
|
||||||
],
|
|
||||||
"fileStates": {
|
|
||||||
"map.tmx": {
|
|
||||||
"scale": 1.5,
|
|
||||||
"selectedLayer": 0,
|
|
||||||
"viewCenter": {
|
|
||||||
"x": 49.33333333333337,
|
|
||||||
"y": 182
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tilemap.tsx": {
|
|
||||||
"dynamicWrapping": false,
|
|
||||||
"scaleInDock": 1.5,
|
|
||||||
"scaleInEditor": 5.5
|
|
||||||
},
|
|
||||||
"tiles.tsx": {
|
|
||||||
"dynamicWrapping": true,
|
|
||||||
"scaleInDock": 1,
|
|
||||||
"scaleInEditor": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"last.imagePath": "/home/rokas/code/games/game-2026-01-18/src/assets/kenney_desert-shooter-pack_1.0/PNG/Tiles/Tilemap",
|
|
||||||
"map.fixedSize": false,
|
|
||||||
"map.lastUsedFormat": "tmx",
|
|
||||||
"map.tileHeight": 16,
|
|
||||||
"map.tileWidth": 16,
|
|
||||||
"openFiles": [
|
|
||||||
"tilemap.tsx",
|
|
||||||
"map.tmx"
|
|
||||||
],
|
|
||||||
"project": "game-2026-01-18.tiled-project",
|
|
||||||
"recentFiles": [
|
|
||||||
"tilemap.tsx",
|
|
||||||
"map.tmx",
|
|
||||||
"tiles.tsx"
|
|
||||||
],
|
|
||||||
"tileset.lastUsedFormat": "tsx",
|
|
||||||
"tileset.tileSize": {
|
|
||||||
"height": 16,
|
|
||||||
"width": 16
|
|
||||||
},
|
|
||||||
"tileset.type": 0
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 216 B |
|
Before Width: | Height: | Size: 232 B |
|
Before Width: | Height: | Size: 189 B |
|
Before Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 244 B |
|
Before Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 243 B |
|
Before Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 227 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 181 B |
|
Before Width: | Height: | Size: 187 B |
|
Before Width: | Height: | Size: 183 B |
|
Before Width: | Height: | Size: 136 B |
|
Before Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 163 B |
|
Before Width: | Height: | Size: 145 B |
|
Before Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 182 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 181 B |
|
Before Width: | Height: | Size: 176 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 176 B |
|
Before Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 125 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 113 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 113 B |
|
Before Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 99 B |
|
Before Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 186 B |
|
Before Width: | Height: | Size: 188 B |
|
Before Width: | Height: | Size: 186 B |
|
Before Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 143 B |
|
Before Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 122 B |
|
Before Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 162 B |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 143 B |
|
Before Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 187 B |
|
Before Width: | Height: | Size: 122 B |
|
Before Width: | Height: | Size: 185 B |
|
Before Width: | Height: | Size: 167 B |
|
Before Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 177 B |
|
Before Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 139 B |
|
Before Width: | Height: | Size: 133 B |
|
Before Width: | Height: | Size: 139 B |
|
Before Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 133 B |
|
Before Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 114 B |
|
Before Width: | Height: | Size: 110 B |
|
Before Width: | Height: | Size: 115 B |
|
Before Width: | Height: | Size: 149 B |