dos3d

annotate src/texture.c @ 19:c10f62b2bd56

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 30 Nov 2011 07:17:09 +0200
parents c8ffdbc6139e
children
rev   line source
nuclear@3 1 /*
nuclear@3 2 256-color 3D graphics hack for real-mode DOS.
nuclear@3 3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
nuclear@3 4
nuclear@3 5 This program is free software: you can redistribute it and/or modify
nuclear@3 6 it under the terms of the GNU General Public License as published by
nuclear@3 7 the Free Software Foundation, either version 3 of the License, or
nuclear@3 8 (at your option) any later version.
nuclear@3 9
nuclear@3 10 This program is distributed in the hope that it will be useful,
nuclear@3 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@3 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@3 13 GNU General Public License for more details.
nuclear@3 14
nuclear@3 15 You should have received a copy of the GNU General Public License
nuclear@3 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@3 17 */
nuclear@3 18
nuclear@4 19 #include <stdio.h>
nuclear@4 20 #include <string.h>
nuclear@3 21 #include <stdlib.h>
nuclear@3 22 #include "texture.h"
nuclear@3 23 #include "palman.h"
nuclear@3 24
nuclear@4 25 struct texture *load_texture(const char *fname)
nuclear@3 26 {
nuclear@19 27 int i, num_pixels, hdrline = 0;
nuclear@4 28 struct texture *tex;
nuclear@4 29 long fpos;
nuclear@4 30
nuclear@4 31 if(!(tex = malloc(sizeof *tex))) {
nuclear@4 32 return 0;
nuclear@4 33 }
nuclear@4 34 memset(tex, 0, sizeof *tex);
nuclear@4 35
nuclear@4 36 if(!(tex->file = fopen(fname, "rb"))) {
nuclear@4 37 fprintf(stderr, "failed to open texture: %s\n", fname);
nuclear@4 38 free_texture(tex);
nuclear@4 39 return 0;
nuclear@4 40 }
nuclear@19 41
nuclear@19 42 while(hdrline < 3) {
nuclear@19 43 char buf[64];
nuclear@19 44 if(!fgets(buf, sizeof buf, tex->file)) {
nuclear@19 45 fprintf(stderr, "invalid pixmap: %s\n", fname);
nuclear@19 46 free_texture(tex);
nuclear@19 47 return 0;
nuclear@19 48 }
nuclear@19 49
nuclear@19 50 if(buf[0] == '#') {
nuclear@19 51 continue;
nuclear@19 52 }
nuclear@19 53
nuclear@19 54 switch(hdrline) {
nuclear@19 55 case 0:
nuclear@19 56 if(buf[0] != 'P' || buf[1] != '6') {
nuclear@19 57 fprintf(stderr, "invalid pixmap: %s\n", fname);
nuclear@19 58 free_texture(tex);
nuclear@19 59 return 0;
nuclear@19 60 }
nuclear@19 61 break;
nuclear@19 62
nuclear@19 63 case 1:
nuclear@19 64 if(sscanf(buf, "%d %d", &tex->width, &tex->height) != 2) {
nuclear@19 65 fprintf(stderr, "invalid pixmap: %s\n", fname);
nuclear@19 66 free_texture(tex);
nuclear@19 67 return 0;
nuclear@19 68 }
nuclear@19 69 break;
nuclear@19 70
nuclear@19 71 case 2:
nuclear@19 72 if(atoi(buf) != 255) {
nuclear@19 73 fprintf(stderr, "invalid pixmap: %s\n", fname);
nuclear@19 74 free_texture(tex);
nuclear@19 75 return 0;
nuclear@19 76 }
nuclear@19 77 break;
nuclear@19 78 }
nuclear@19 79 hdrline++;
nuclear@4 80 }
nuclear@4 81 fpos = ftell(tex->file);
nuclear@4 82
nuclear@4 83 num_pixels = tex->width * tex->height;
nuclear@4 84 for(i=0; i<num_pixels; i++) {
nuclear@4 85 int r, g, b;
nuclear@4 86
nuclear@4 87 r = fgetc(tex->file);
nuclear@4 88 g = fgetc(tex->file);
nuclear@4 89 b = fgetc(tex->file);
nuclear@4 90
nuclear@4 91 if(feof(tex->file)) {
nuclear@4 92 fprintf(stderr, "unexpected EOF while reading: %s\n", fname);
nuclear@4 93 free_texture(tex);
nuclear@4 94 return 0;
nuclear@4 95 }
nuclear@4 96
nuclear@4 97 if(palm_color_index(r, g, b) == -1) {
nuclear@4 98 palm_add_color(r, g, b);
nuclear@4 99 }
nuclear@4 100 }
nuclear@4 101 fseek(tex->file, fpos, SEEK_SET);
nuclear@4 102 return tex;
nuclear@4 103 }
nuclear@4 104
nuclear@4 105 void free_texture(struct texture *tex)
nuclear@4 106 {
nuclear@4 107 if(tex) {
nuclear@4 108 if(tex->file) {
nuclear@4 109 fclose(tex->file);
nuclear@4 110 }
nuclear@4 111 free(tex->pixels);
nuclear@4 112 free(tex);
nuclear@4 113 }
nuclear@4 114 }
nuclear@4 115
nuclear@4 116 unsigned char *get_texture_pixels(struct texture *tex)
nuclear@4 117 {
nuclear@4 118 if(!tex->pixels && tex->file) {
nuclear@4 119 int i, num_pixels = tex->width * tex->height;
nuclear@4 120
nuclear@4 121 if(!(tex->pixels = malloc(num_pixels))) {
nuclear@4 122 return 0;
nuclear@4 123 }
nuclear@4 124
nuclear@4 125 for(i=0; i<num_pixels; i++) {
nuclear@4 126 int r, g, b, base;
nuclear@4 127
nuclear@4 128 r = fgetc(tex->file);
nuclear@4 129 g = fgetc(tex->file);
nuclear@4 130 b = fgetc(tex->file);
nuclear@4 131
nuclear@4 132 if((base = palm_color_base(r, g, b)) == -1) {
nuclear@4 133 base = 0;
nuclear@4 134 }
nuclear@4 135 tex->pixels[i] = base;
nuclear@4 136 }
nuclear@4 137
nuclear@4 138 fclose(tex->file);
nuclear@4 139 tex->file = 0;
nuclear@4 140 }
nuclear@4 141
nuclear@4 142 return tex->pixels;
nuclear@3 143 }
nuclear@3 144
nuclear@3 145 struct texture *tex_gen_checker(int xsz, int ysz, int ush, int vsh, int c1, int c2)
nuclear@3 146 {
nuclear@3 147 int i, j;
nuclear@3 148 struct texture *tex;
nuclear@3 149 unsigned char *pptr;
nuclear@3 150
nuclear@3 151 if(!(tex = malloc(sizeof *tex))) {
nuclear@3 152 return 0;
nuclear@3 153 }
nuclear@4 154 memset(tex, 0, sizeof *tex);
nuclear@4 155
nuclear@3 156 if(!(tex->pixels = malloc(xsz * ysz))) {
nuclear@3 157 free(tex);
nuclear@3 158 return 0;
nuclear@3 159 }
nuclear@3 160 tex->width = xsz;
nuclear@3 161 tex->height = ysz;
nuclear@3 162
nuclear@3 163 pptr = tex->pixels;
nuclear@3 164 for(i=0; i<ysz; i++) {
nuclear@3 165 for(j=0; j<xsz; j++) {
nuclear@3 166 int c = ((i >> vsh) & 1) == ((j >> ush) & 1) ? c1 : c2;
nuclear@3 167 *pptr++ = c;
nuclear@3 168 }
nuclear@3 169 }
nuclear@3 170 return tex;
nuclear@3 171 }