/* * Kangaroo Punch MultiPlayer Game Server Mark II * Copyright (C) 2020-2021 Scott Duensing * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #define STB_IMAGE_IMPLEMENTATION #define STBI_ONLY_PNG #include "image.h" ImageT *imageAllocate(uint16_t w, uint16_t h) { uint16_t x; uint16_t y; ImageT *image; // Create new native image image = (ImageT *)malloc(sizeof(ImageT)); if (!image) return NULL; image->width = w; image->height = h; // Create space for converted pixel data - columns image->pixels = (ColorT **)malloc(sizeof(ColorT *) * image->width); if (!image->pixels) { free(image); return NULL; } // Create space for converted pixel data - rows for (x=0; xwidth; x++) { image->pixels[x] = (ColorT *)malloc(sizeof(ColorT) * image->height); if (!image->pixels[x]) { for (y=0; ypixels[y]); } free(image->pixels); free(image); return NULL; } } return image; } ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color) { uint16_t x; uint16_t y; ImageT *image = imageAllocate(w, h); if (!image) return NULL; for (y=0; yheight; y++) { for (x=0; xwidth; x++) { image->pixels[x][y] = color; } } return image; } uint16_t imageHeightGet(ImageT *image) { return image->height; } uint8_t imageInfoGet(char *filename, uint16_t *width, uint16_t *height) { int w; // Using boring old compiler 'int' on purpose. int h; int n; int r; r = stbi_info(filename, &w, &h, &n); if (r) { *width = w; *height = h; return 1; } return 0; } ImageT *imageLoad(char *filename) { uint16_t x; uint16_t y; uint16_t n; uint32_t b; unsigned char *raw; ImageT *image; // Load image from disk raw = stbi_load(filename, (int *)&x, (int *)&y, (int *)&n, 3); if (!raw) return NULL; // Create native image. image = imageAllocate(x, y); if (!image) { stbi_image_free(raw); return NULL; } // Convert from RGB to our generic 32 bit pixel format b = 0; for (y=0; yheight; y++) { for (x=0; xwidth; x++) { image->pixels[x][y] = vbeMakeColor(raw[b], raw[b + 1], raw[b + 2]); b += 3; } } stbi_image_free(raw); return image; } ColorT imagePixelGet(ImageT *image, uint16_t x, uint16_t y) { return image->pixels[x][y]; } void imageRender(ImageT *image, uint16_t x, uint16_t y) { uint16_t x1; uint16_t y1; uint16_t x2 = image->width; uint16_t y2 = image->height; // Clip on right and bottom if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet(); if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet(); for (y1=0; y1pixels[x1][y1]); } } } void imageRenderWithAlpha(ImageT *image, uint16_t x, uint16_t y, ColorT alpha) { uint16_t x1; uint16_t y1; uint16_t x2 = image->width; uint16_t y2 = image->height; // Clip on right and bottom if (x + x2 > vbeSurfaceWidthGet()) x2 -= x + x2 - vbeSurfaceWidthGet(); if (y + y2 > vbeSurfaceHeightGet()) y2 -= y + y2 - vbeSurfaceHeightGet(); for (y1=0; y1pixels[x1][y1]) { vbePutPixel(x + x1, y + y1, image->pixels[x1][y1]); } } } } void imageUnload(ImageT **image) { uint16_t x; ImageT *i = *image; for (x=0; xwidth; x++) { free(i->pixels[x]); } free(i->pixels); free(i); i = NULL; } uint16_t imageWidthGet(ImageT *image) { return image->width; }