amiga_imgv

changeset 3:663471a80c21

broken + sdl emu
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 26 Oct 2017 15:49:56 +0300
parents f75893a33234
children 0fd37effde29
files Makefile src/amiga/gfx.c src/gfx.h src/image.c src/main.c src/sdl/gfx.c tools/convhammer/main.c
diffstat 7 files changed, 319 insertions(+), 44 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Thu Oct 26 10:04:29 2017 +0300
     1.2 +++ b/Makefile	Thu Oct 26 15:49:56 2017 +0300
     1.3 @@ -1,10 +1,18 @@
     1.4 -src = $(wildcard src/*.c) $(wildcard src/amiga/*.c)
     1.5 +src = $(wildcard src/*.c)
     1.6  obj = $(src:.c=.o)
     1.7  bin = imgv
     1.8  
     1.9  CC = vc
    1.10 -CFLAGS = -Isrc -Isrc/amiga
    1.11 -LDFLAGS = -lamiga
    1.12 +
    1.13 +ifeq ($(CC), vc)
    1.14 +	CFLAGS = -Isrc -Isrc/amiga
    1.15 +	LDFLAGS = -lamiga
    1.16 +	src += $(wildcard src/amiga/*.c)
    1.17 +else
    1.18 +	CFLAGS = -pedantic -Wall -g -Isrc -Isrc/sdl `sdl-config --cflags`
    1.19 +	LDFLAGS = `sdl-config --libs`
    1.20 +	src += $(wildcard src/sdl/*.c)
    1.21 +endif
    1.22  
    1.23  $(bin): $(obj)
    1.24  	$(CC) -o $@ $(obj) $(LDFLAGS)
     2.1 --- a/src/amiga/gfx.c	Thu Oct 26 10:04:29 2017 +0300
     2.2 +++ b/src/amiga/gfx.c	Thu Oct 26 15:49:56 2017 +0300
     2.3 @@ -57,6 +57,7 @@
     2.4  	gfx_begin_copperlist();
     2.5  	add_copper(COPPER_END);
     2.6  
     2.7 +	logmsg("starting DMA\n");
     2.8  	REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER);
     2.9  	return 0;
    2.10  }
    2.11 @@ -201,3 +202,7 @@
    2.12  {
    2.13  	gfx_wait_vpos(300);
    2.14  }
    2.15 +
    2.16 +void gfx_show_image(struct ham_image *img)
    2.17 +{
    2.18 +}
     3.1 --- a/src/gfx.h	Thu Oct 26 10:04:29 2017 +0300
     3.2 +++ b/src/gfx.h	Thu Oct 26 15:49:56 2017 +0300
     3.3 @@ -47,6 +47,8 @@
     3.4  	int width, height;
     3.5  };
     3.6  
     3.7 +struct ham_image;
     3.8 +
     3.9  int gfx_init(int nbpl, unsigned int flags);
    3.10  void gfx_shutdown(void);
    3.11  
    3.12 @@ -66,4 +68,6 @@
    3.13  void gfx_wait_vpos(int x);
    3.14  void gfx_wait_vblank(void);
    3.15  
    3.16 +void gfx_show_image(struct ham_image *img);
    3.17 +
    3.18  #endif	/* GFX_H_ */
     4.1 --- a/src/image.c	Thu Oct 26 10:04:29 2017 +0300
     4.2 +++ b/src/image.c	Thu Oct 26 15:49:56 2017 +0300
     4.3 @@ -1,10 +1,122 @@
     4.4 +#include <stdio.h>
     4.5  #include <stdlib.h>
     4.6  #include <string.h>
     4.7 +#include <errno.h>
     4.8  #include "image.h"
     4.9 +#include "logger.h"
    4.10 +
    4.11 +#ifdef __unix__
    4.12 +#include <arpa/inet.h>
    4.13 +#define HAVE_NTOHS
    4.14 +#else
    4.15 +static int bigendian(void);
    4.16 +static uint16_t swap16(uint16_t x);
    4.17 +static uint16_t nop16(uint16_t x);
    4.18 +static uint16_t (*ntohs)(uint16_t);
    4.19 +#endif
    4.20 +
    4.21 +struct ham_image_header {
    4.22 +	char magic[4];
    4.23 +	uint16_t width, height;
    4.24 +	unsigned char nbitplanes, padding;
    4.25 +	uint16_t nchg;
    4.26 +	uint16_t palette[16];
    4.27 +};
    4.28  
    4.29  struct ham_image *load_ham_image(const char *fname)
    4.30  {
    4.31 -	return 0;	/* TODO */
    4.32 +	int i, num;
    4.33 +	unsigned long imgsz;
    4.34 +	struct ham_image_header hdr;
    4.35 +	struct ham_image *img = 0;
    4.36 +	struct palchange *tail = 0;
    4.37 +	FILE *fp;
    4.38 +
    4.39 +#ifndef HAVE_NTOHS
    4.40 +	ntohs = bigendian() ? nop16 : swap16;
    4.41 +#endif
    4.42 +
    4.43 +	logmsg("opening file: %s\n", fname);
    4.44 +	if(!(fp = fopen(fname, "rb"))) {
    4.45 +		logmsg("failed to open %s: %s\n", fname, strerror(errno));
    4.46 +		return 0;
    4.47 +	}
    4.48 +
    4.49 +	if(fread(&hdr, sizeof hdr, 1, fp) < 1) {
    4.50 +		logmsg("unexpected eof while reading image header\n");
    4.51 +		goto err;
    4.52 +	}
    4.53 +	if(memcmp(hdr.magic, "HAAM", 4) != 0) {
    4.54 +		logmsg("failed to load image: %s: unknown file type\n", fname);
    4.55 +		goto err;
    4.56 +	}
    4.57 +
    4.58 +	if(!(img = malloc(sizeof *img))) {
    4.59 +		logmsg("failed to allocate image structure\n");
    4.60 +		goto err;
    4.61 +	}
    4.62 +	img->width = ntohs(hdr.width);
    4.63 +	img->height = ntohs(hdr.height);
    4.64 +	img->nbitplanes = hdr.nbitplanes;
    4.65 +
    4.66 +	imgsz = img->width * img->height / 8 * img->nbitplanes;
    4.67 +
    4.68 +	logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz);
    4.69 +
    4.70 +	if(!(img->pixels = malloc(imgsz))) {
    4.71 +		logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes);
    4.72 +		goto err;
    4.73 +	}
    4.74 +
    4.75 +	for(i=0; i<16; i++) {
    4.76 +		img->palette[i] = ntohs(hdr.palette[i]);
    4.77 +	}
    4.78 +
    4.79 +	num = ntohs(hdr.nchg);
    4.80 +	for(i=0; i<num; i++) {
    4.81 +		struct palchange *chg;
    4.82 +
    4.83 +		if(!(chg = malloc(sizeof *chg))) {
    4.84 +			logmsg("failed to allocate palchange structure\n");
    4.85 +			goto err;
    4.86 +		}
    4.87 +
    4.88 +		if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) {
    4.89 +			logmsg("unexpected end of file while reading palette changelist\n");
    4.90 +			goto err;
    4.91 +		}
    4.92 +		chg->line = ntohs(chg->line);
    4.93 +		chg->entry = ntohs(chg->entry);
    4.94 +		chg->next = 0;
    4.95 +
    4.96 +		if(tail) {
    4.97 +			tail->next = chg;
    4.98 +			tail = chg;
    4.99 +		} else {
   4.100 +			img->chglist = tail = chg;
   4.101 +		}
   4.102 +	}
   4.103 +
   4.104 +	if(fread(img->pixels, 1, imgsz, fp) < imgsz) {
   4.105 +		logmsg("unexpected end of file while reading image pixels\n");
   4.106 +		goto err;
   4.107 +	}
   4.108 +
   4.109 +	fclose(fp);
   4.110 +	return img;
   4.111 +
   4.112 +err:
   4.113 +	if(img) {
   4.114 +		while(img->chglist) {
   4.115 +			void *tmp = img->chglist;
   4.116 +			img->chglist = img->chglist->next;
   4.117 +			free(tmp);
   4.118 +		}
   4.119 +		free(img->pixels);
   4.120 +		free(img);
   4.121 +	}
   4.122 +	if(fp) fclose(fp);
   4.123 +	return 0;
   4.124  }
   4.125  
   4.126  struct ham_image *gen_ham_image(int w, int h, int nbpl)
   4.127 @@ -53,3 +165,21 @@
   4.128  
   4.129  	return img;
   4.130  }
   4.131 +
   4.132 +#ifndef HAVE_NTOHS
   4.133 +static int bigendian(void)
   4.134 +{
   4.135 +	static const uint16_t x = 0xaabb;
   4.136 +	return *(unsigned char*)&x == 0xaa;
   4.137 +}
   4.138 +
   4.139 +static uint16_t swap16(uint16_t x)
   4.140 +{
   4.141 +	return (x << 8) | (x >> 8);
   4.142 +}
   4.143 +
   4.144 +static uint16_t nop16(uint16_t x)
   4.145 +{
   4.146 +	return x;
   4.147 +}
   4.148 +#endif
     5.1 --- a/src/main.c	Thu Oct 26 10:04:29 2017 +0300
     5.2 +++ b/src/main.c	Thu Oct 26 15:49:56 2017 +0300
     5.3 @@ -6,14 +6,8 @@
     5.4  #include "image.h"
     5.5  #include "logger.h"
     5.6  
     5.7 -#include "hwregs.h"
     5.8 -#include "copper.h"
     5.9 -
    5.10  
    5.11  static int proc_event(union gfx_event *ev);
    5.12 -static void show_ham_image(struct ham_image *img);
    5.13 -
    5.14 -static int win_width, win_height;
    5.15  
    5.16  int main(int argc, char **argv)
    5.17  {
    5.18 @@ -36,7 +30,7 @@
    5.19  		return 1;
    5.20  	}
    5.21  	gfx_wait_vblank();
    5.22 -	show_ham_image(img);
    5.23 +	gfx_show_image(img);
    5.24  
    5.25  	for(;;) {
    5.26  		union gfx_event ev;
    5.27 @@ -71,36 +65,3 @@
    5.28  	}
    5.29  	return 0;
    5.30  }
    5.31 -
    5.32 -#define NUM_BPL		6
    5.33 -static void show_ham_image(struct ham_image *img)
    5.34 -{
    5.35 -	int i, j, k, fbwidth, fbheight, ncolors, prev_line;
    5.36 -	unsigned char *fbptr = gfx_get_framebuffer();
    5.37 -	struct palchange *chg = img->chglist;
    5.38 -
    5.39 -	fbwidth = gfx_framebuffer_width();
    5.40 -	fbheight = gfx_framebuffer_height();
    5.41 -
    5.42 -	memcpy(fbptr, img->pixels, fbwidth * fbheight / 8 * NUM_BPL);
    5.43 -
    5.44 -	/* create copper list that handles the palette */
    5.45 -	clear_copper();
    5.46 -	gfx_begin_copperlist();
    5.47 -	/* initial palette at the start of frame */
    5.48 -	for(i=0; i<16; i++) {
    5.49 -		add_copper(COPPER_MOVE(REGN_COLOR(i), img->palette[i]));
    5.50 -		logmsg("copper palette[%d]: %x\n", i, (unsigned int)img->palette[i]);
    5.51 -	}
    5.52 -	/* add copper instructions for palette changes according to the image changelist */
    5.53 -	prev_line = -1;
    5.54 -	while(chg) {
    5.55 -		assert(chg->line >= prev_line);
    5.56 -		if(chg->line != prev_line) {
    5.57 -			prev_line = chg->line;
    5.58 -			add_copper(COPPER_VWAIT(chg->line));
    5.59 -		}
    5.60 -		add_copper(COPPER_MOVE(REGN_COLOR(chg->entry >> 12), chg->entry & 0xfff));
    5.61 -	}
    5.62 -	add_copper(COPPER_END);
    5.63 -}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/sdl/gfx.c	Thu Oct 26 15:49:56 2017 +0300
     6.3 @@ -0,0 +1,160 @@
     6.4 +#include <stdio.h>
     6.5 +#include <SDL/SDL.h>
     6.6 +#include "gfx.h"
     6.7 +#include "image.h"
     6.8 +
     6.9 +static SDL_Surface *fbsurf;
    6.10 +static int scr_width, scr_height;
    6.11 +static int fb_width, fb_height;
    6.12 +static int num_bitplanes;
    6.13 +
    6.14 +
    6.15 +int gfx_init(int nbpl, unsigned int flags)
    6.16 +{
    6.17 +	num_bitplanes = nbpl;
    6.18 +	scr_width = fb_width = (flags & GFX_HIRES) ? 640 : 320;
    6.19 +	scr_height = fb_height = (flags & GFX_ILACE) ? 512 : 256;
    6.20 +
    6.21 +	if(SDL_Init(SDL_INIT_VIDEO) == -1) {
    6.22 +		fprintf(stderr, "failed to initialize SDL\n");
    6.23 +		return -1;
    6.24 +	}
    6.25 +	if(!(fbsurf = SDL_SetVideoMode(scr_width, scr_height, 32, SDL_SWSURFACE))) {
    6.26 +		fprintf(stderr, "failed to set video mode %dx%d\n", scr_width, scr_height);
    6.27 +		SDL_Quit();
    6.28 +		return -1;
    6.29 +	}
    6.30 +
    6.31 +	return 0;
    6.32 +}
    6.33 +
    6.34 +void gfx_shutdown(void)
    6.35 +{
    6.36 +	SDL_Quit();
    6.37 +}
    6.38 +
    6.39 +
    6.40 +int gfx_screen_width(void)
    6.41 +{
    6.42 +	return scr_width;
    6.43 +}
    6.44 +
    6.45 +int gfx_screen_height(void)
    6.46 +{
    6.47 +	return scr_height;
    6.48 +}
    6.49 +
    6.50 +
    6.51 +void *gfx_set_framebuffer(void *fb, int width, int height)
    6.52 +{
    6.53 +	return 0;
    6.54 +}
    6.55 +
    6.56 +void *gfx_get_framebuffer(void)
    6.57 +{
    6.58 +	return 0;
    6.59 +}
    6.60 +
    6.61 +
    6.62 +int get_framebuffer_width(void)
    6.63 +{
    6.64 +	return fb_width;
    6.65 +}
    6.66 +
    6.67 +int get_framebuffer_height(void)
    6.68 +{
    6.69 +	return fb_height;
    6.70 +}
    6.71 +
    6.72 +
    6.73 +void gfx_begin_copperlist(void)
    6.74 +{
    6.75 +}
    6.76 +
    6.77 +
    6.78 +int gfx_next_event(union gfx_event *ev, int block)
    6.79 +{
    6.80 +	SDL_Event sdlev;
    6.81 +
    6.82 +	if(block) {
    6.83 +		SDL_WaitEvent(&sdlev);
    6.84 +	} else {
    6.85 +		if(!SDL_PollEvent(&sdlev)) {
    6.86 +			return 0;
    6.87 +		}
    6.88 +	}
    6.89 +
    6.90 +	switch(sdlev.type) {
    6.91 +	case SDL_QUIT:
    6.92 +		ev->type = GFX_EV_QUIT;
    6.93 +		return 1;
    6.94 +
    6.95 +	case SDL_KEYDOWN:
    6.96 +	case SDL_KEYUP:
    6.97 +		ev->type = GFX_EV_KEY;
    6.98 +		ev->key.key = sdlev.key.keysym.sym;
    6.99 +		ev->key.pressed = sdlev.key.state == SDL_PRESSED;
   6.100 +		return 1;
   6.101 +
   6.102 +	default:
   6.103 +		break;
   6.104 +	}
   6.105 +	return 0;
   6.106 +}
   6.107 +
   6.108 +
   6.109 +void gfx_wait_vpos(int x)
   6.110 +{
   6.111 +}
   6.112 +
   6.113 +void gfx_wait_vblank(void)
   6.114 +{
   6.115 +}
   6.116 +
   6.117 +#define ARED(x)		((((x) & 0xf00) >> 4) | (((x) & 0xf00) >> 8))
   6.118 +#define AGREEN(x)	(((x) & 0xf0) | (((x) & 0xf0) >> 4))
   6.119 +#define ABLUE(x)	((((x) & 0xf) << 4) | ((x) & 0xf))
   6.120 +
   6.121 +void gfx_show_image(struct ham_image *img)
   6.122 +{
   6.123 +	int i, j, k;
   6.124 +	uint32_t palette[16];
   6.125 +	uint32_t *dest;
   6.126 +	unsigned char *src;
   6.127 +
   6.128 +	for(i=0; i<16; i++) {
   6.129 +		uint16_t pcol = img->palette[i];
   6.130 +		int red = ARED(pcol);
   6.131 +		int green = AGREEN(pcol);
   6.132 +		int blue = ABLUE(pcol);
   6.133 +		palette[i] = (red << fbsurf->format->Rshift) | (green << fbsurf->format->Gshift) |
   6.134 +			(blue << fbsurf->format->Bshift);
   6.135 +	}
   6.136 +
   6.137 +	if(SDL_MUSTLOCK(fbsurf)) {
   6.138 +		SDL_LockSurface(fbsurf);
   6.139 +	}
   6.140 +
   6.141 +	dest = fbsurf->pixels;
   6.142 +	src = img->pixels;
   6.143 +	for(i=0; i<img->height; i++) {
   6.144 +		for(j=0; j<img->width; j++) {
   6.145 +			unsigned char idx = 0;
   6.146 +			int bit = j & 7;
   6.147 +			for(k=0; k<img->nbitplanes; k++) {
   6.148 +				idx = (idx << 1) | ((*(src + k * img->width / 8) >> bit) & 1);
   6.149 +			}
   6.150 +			*dest++ = palette[idx];
   6.151 +			if(bit == 7) {
   6.152 +				++src;
   6.153 +			}
   6.154 +		}
   6.155 +		src += img->width / 8 * (img->nbitplanes - 1);
   6.156 +	}
   6.157 +
   6.158 +	if(SDL_MUSTLOCK(fbsurf)) {
   6.159 +		SDL_UnlockSurface(fbsurf);
   6.160 +	}
   6.161 +
   6.162 +	SDL_Flip(fbsurf);
   6.163 +}
     7.1 --- a/tools/convhammer/main.c	Thu Oct 26 10:04:29 2017 +0300
     7.2 +++ b/tools/convhammer/main.c	Thu Oct 26 15:49:56 2017 +0300
     7.3 @@ -167,6 +167,8 @@
     7.4  		}
     7.5  	}
     7.6  
     7.7 +	free(inpixels);
     7.8 +	fclose(fp);
     7.9  	return img;
    7.10  
    7.11  err:
    7.12 @@ -215,6 +217,11 @@
    7.13  	num = htons(num);
    7.14  	fwrite(&num, 2, 1, fp);
    7.15  
    7.16 +	for(i=0; i<16; i++) {
    7.17 +		val = htons(img->palette[i]);
    7.18 +		fwrite(&val, 2, 1, fp);
    7.19 +	}
    7.20 +
    7.21  	chg = img->chglist;
    7.22  	while(chg) {
    7.23  		val = htons(chg->line);