diff options
| author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-09-08 23:25:51 +0900 | 
|---|---|---|
| committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-09-08 23:25:51 +0900 | 
| commit | 50c75c12597b230cec4d7a29559cde263025eeb2 (patch) | |
| tree | 9fa8afe8bcf6e1219186e5c567930831a3b5eab5 /pacc | |
| parent | 4cfeddd04dcbbf658195bd837d7daff7f08b37bc (diff) | |
pacc: initial
Diffstat (limited to 'pacc')
40 files changed, 2441 insertions, 0 deletions
| diff --git a/pacc/glsl/Makefile b/pacc/glsl/Makefile new file mode 100644 index 0000000..36aace4 --- /dev/null +++ b/pacc/glsl/Makefile @@ -0,0 +1,40 @@ +VSHADERS:=blit.vert +FSHADERS:=copy.frag color.frag color_trans.frag key.frag fill.frag font.frag +DSHEADER:=dsheader +ESHEADER:=esheader +INCS:=$(addsuffix .inc,$(VSHADERS) $(FSHADERS) $(DSHEADER) $(ESHEADER)) +SHADERS2:=$(addsuffix .ds.vert,$(basename $(VSHADERS))) +SHADERS2+=$(addsuffix .es.vert,$(basename $(VSHADERS))) +SHADERS2+=$(addsuffix .ds.frag,$(basename $(FSHADERS))) +SHADERS2+=$(addsuffix .es.frag,$(basename $(FSHADERS))) +VALS:=$(addsuffix .vald,$(SHADERS2)) +VALIDATOR:=glslangValidator +VFLAGS:= + +all:	$(INCS) + +val:	$(VALS) + +%.es.vert:	%.vert +	cat $(ESHEADER) $< > $@ + +%.es.frag:	%.frag +	cat $(ESHEADER) $< > $@ + +%.ds.vert:	%.vert +	cat $(DSHEADER) $< > $@ + +%.ds.frag:	%.frag +	cat $(DSHEADER) $< > $@ + +%.vald:	% +	$(VALIDATOR) $(VFLAGS) $< + +%.inc:	%.zt +	xxd -i $< | sed -e '/^unsigned char /c\static const uint8_t $(shell echo $(basename $<) | sed -e 's/\./_/g')[] = {' -e '/^unsigned int /c\\' > $@ + +%.zt:	% +	dd bs=1 count=1 if=/dev/zero | cat $< - > $@ + +clean: +	rm -f $(INCS) diff --git a/pacc/glsl/blit.vert b/pacc/glsl/blit.vert new file mode 100644 index 0000000..4232a8d --- /dev/null +++ b/pacc/glsl/blit.vert @@ -0,0 +1,7 @@ +attribute vec4 coord; +varying vec2 texcoord; +void main(void) { +  gl_Position = vec4(coord.xy, 0.0, 1.0); +  texcoord = coord.zw; +} + diff --git a/pacc/glsl/blit.vert.inc b/pacc/glsl/blit.vert.inc new file mode 100644 index 0000000..34691a9 --- /dev/null +++ b/pacc/glsl/blit.vert.inc @@ -0,0 +1,14 @@ +static const uint8_t blit_vert[] = { +  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x65, +  0x63, 0x34, 0x20, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, +  0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, 0x69, +  0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, +  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, +  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, +  0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x30, 0x2e, +  0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, +  0x6f, 0x72, 0x64, 0x2e, 0x7a, 0x77, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/color.frag b/pacc/glsl/color.frag new file mode 100644 index 0000000..d03bee5 --- /dev/null +++ b/pacc/glsl/color.frag @@ -0,0 +1,13 @@ +uniform sampler2D palette; +uniform sampler2D tex; +varying mediump vec2 texcoord; +uniform lowp float color; +void main(void) { +  lowp float index = texture2D(tex, texcoord).x; +  if (index > (0.5/255.0)) { +    index = color; +  } else { +    index = 0.5 / 256.0; +  } +  gl_FragColor = texture2D(palette, vec2(index, 0.0)); +} diff --git a/pacc/glsl/color.frag.inc b/pacc/glsl/color.frag.inc new file mode 100644 index 0000000..8ea77ef --- /dev/null +++ b/pacc/glsl/color.frag.inc @@ -0,0 +1,30 @@ +static const uint8_t color_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, +  0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, +  0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, +  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x76, +  0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, +  0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, +  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, +  0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, +  0x74, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, +  0x64, 0x29, 0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, +  0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3e, 0x20, 0x28, 0x30, 0x2e, 0x35, +  0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, +  0x20, 0x20, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x63, +  0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, +  0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x64, +  0x65, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2f, 0x20, 0x32, +  0x35, 0x36, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, +  0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, +  0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, +  0x28, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, +  0x63, 0x32, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x30, 0x2e, +  0x30, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/color_trans.frag b/pacc/glsl/color_trans.frag new file mode 100644 index 0000000..ef742a4 --- /dev/null +++ b/pacc/glsl/color_trans.frag @@ -0,0 +1,11 @@ +uniform sampler2D palette; +uniform sampler2D tex; +varying mediump vec2 texcoord; +uniform lowp float color; +void main(void) { +  lowp float index = texture2D(tex, texcoord).x; +  if (index < (0.5/255.0)) { +    discard; +  } +  gl_FragColor = texture2D(palette, vec2(color, 0.0)); +} diff --git a/pacc/glsl/color_trans.frag.inc b/pacc/glsl/color_trans.frag.inc new file mode 100644 index 0000000..f49404c --- /dev/null +++ b/pacc/glsl/color_trans.frag.inc @@ -0,0 +1,27 @@ +static const uint8_t color_trans_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, +  0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, +  0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, +  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x76, +  0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, +  0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, +  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, +  0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, +  0x74, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, +  0x64, 0x29, 0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, +  0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3c, 0x20, 0x28, 0x30, 0x2e, 0x35, +  0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, +  0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x0a, +  0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, +  0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, +  0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x70, 0x61, 0x6c, 0x65, 0x74, +  0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x63, 0x6f, 0x6c, +  0x6f, 0x72, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x7d, +  0x0a, 0x00 +}; + diff --git a/pacc/glsl/copy.frag b/pacc/glsl/copy.frag new file mode 100644 index 0000000..a77ad91 --- /dev/null +++ b/pacc/glsl/copy.frag @@ -0,0 +1,9 @@ +uniform sampler2D palette; +uniform sampler2D tex; +varying mediump vec2 texcoord; +void main(void) { +  lowp float index = texture2D(tex, texcoord).x; +  lowp float color = (index * 255.0 + 0.5) / 256.0; +  gl_FragColor = texture2D(palette, vec2(color, 0.0)); +} + diff --git a/pacc/glsl/copy.frag.inc b/pacc/glsl/copy.frag.inc new file mode 100644 index 0000000..fa3f388 --- /dev/null +++ b/pacc/glsl/copy.frag.inc @@ -0,0 +1,25 @@ +static const uint8_t copy_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, +  0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, +  0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, 0x69, +  0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, +  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, +  0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, +  0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x29, +  0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, +  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, +  0x20, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2a, 0x20, 0x32, 0x35, +  0x35, 0x2e, 0x30, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x2f, +  0x20, 0x32, 0x35, 0x36, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, +  0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, +  0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x70, +  0x61, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, +  0x28, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, +  0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/dsheader b/pacc/glsl/dsheader new file mode 100644 index 0000000..13e65b7 --- /dev/null +++ b/pacc/glsl/dsheader @@ -0,0 +1,5 @@ +#version 110 +#define lowp +#define mediump +#define highp + diff --git a/pacc/glsl/dsheader.inc b/pacc/glsl/dsheader.inc new file mode 100644 index 0000000..b742cec --- /dev/null +++ b/pacc/glsl/dsheader.inc @@ -0,0 +1,8 @@ +static const uint8_t dsheader[] = { +  0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x31, 0x30, +  0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x77, +  0x70, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, +  0x65, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x0a, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/esheader b/pacc/glsl/esheader new file mode 100644 index 0000000..43b26bc --- /dev/null +++ b/pacc/glsl/esheader @@ -0,0 +1,2 @@ +#version 100 + diff --git a/pacc/glsl/esheader.inc b/pacc/glsl/esheader.inc new file mode 100644 index 0000000..3ca61f1 --- /dev/null +++ b/pacc/glsl/esheader.inc @@ -0,0 +1,5 @@ +static const uint8_t esheader[] = { +  0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x30, 0x30, +  0x0a, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/fill.frag b/pacc/glsl/fill.frag new file mode 100644 index 0000000..010b5dc --- /dev/null +++ b/pacc/glsl/fill.frag @@ -0,0 +1,5 @@ +uniform sampler2D palette; +varying mediump vec2 texcoord; +void main(void) { +  gl_FragColor = texture2D(palette, vec2(texcoord.x, 0.0)); +} diff --git a/pacc/glsl/fill.frag.inc b/pacc/glsl/fill.frag.inc new file mode 100644 index 0000000..8065199 --- /dev/null +++ b/pacc/glsl/fill.frag.inc @@ -0,0 +1,15 @@ +static const uint8_t fill_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, +  0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, +  0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, +  0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, +  0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, +  0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, +  0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x70, 0x61, 0x6c, 0x65, 0x74, +  0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, +  0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2c, 0x20, 0x30, 0x2e, 0x30, +  0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/font.frag b/pacc/glsl/font.frag new file mode 100644 index 0000000..8beb0a7 --- /dev/null +++ b/pacc/glsl/font.frag @@ -0,0 +1,15 @@ +uniform sampler2D palette; +uniform sampler2D tex; +varying mediump vec2 texcoord; +uniform lowp float bg; +uniform lowp float color; +void main(void) { +  gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); +  lowp float pixel = texture2D(tex, texcoord).x; +  lowp float index = color; +  if (pixel < 0.5) { +    if (bg < 0.5) discard; +    index = 0.5 / 256.0; +  } +  gl_FragColor = texture2D(palette, vec2(index, 0.0)); +} diff --git a/pacc/glsl/font.frag.inc b/pacc/glsl/font.frag.inc new file mode 100644 index 0000000..27d143d --- /dev/null +++ b/pacc/glsl/font.frag.inc @@ -0,0 +1,37 @@ +static const uint8_t font_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, +  0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, +  0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, +  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x62, 0x67, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, +  0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, 0x6f, +  0x61, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x76, 0x6f, +  0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, +  0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, +  0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, +  0x34, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, +  0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, +  0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, +  0x70, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, +  0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x2e, 0x78, 0x3b, 0x0a, +  0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, +  0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6c, +  0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x69, +  0x78, 0x65, 0x6c, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x7b, +  0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x62, 0x67, 0x20, +  0x3c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, +  0x72, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x64, 0x65, +  0x78, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2f, 0x20, 0x32, 0x35, +  0x36, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x67, +  0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, +  0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, +  0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, 0x63, +  0x32, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x30, 0x2e, 0x30, +  0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; + diff --git a/pacc/glsl/key.frag b/pacc/glsl/key.frag new file mode 100644 index 0000000..d6bf7e1 --- /dev/null +++ b/pacc/glsl/key.frag @@ -0,0 +1,12 @@ +uniform sampler2D palette; +uniform sampler2D tex; +varying mediump vec2 texcoord; +uniform lowp float key; +uniform lowp float color; +void main(void) { +  lowp float index = texture2D(tex, texcoord).x; +  if (index < (key + (0.5/255.0)) || (key + (1.5/255.0)) < index) { +    discard; +  } +  gl_FragColor = texture2D(palette, vec2(color, 0.0)); +} diff --git a/pacc/glsl/key.frag.inc b/pacc/glsl/key.frag.inc new file mode 100644 index 0000000..4a4a6c1 --- /dev/null +++ b/pacc/glsl/key.frag.inc @@ -0,0 +1,32 @@ +static const uint8_t key_frag[] = { +  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, +  0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x74, +  0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, +  0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x74, 0x65, 0x78, +  0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, +  0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, +  0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x75, 0x6e, 0x69, +  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x0a, 0x75, 0x6e, 0x69, +  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x66, 0x6c, +  0x6f, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x76, +  0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, +  0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, +  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, +  0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, +  0x74, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, +  0x64, 0x29, 0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, +  0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3c, 0x20, 0x28, 0x6b, 0x65, 0x79, +  0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x2f, 0x32, 0x35, 0x35, 0x2e, +  0x30, 0x29, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x6b, 0x65, 0x79, 0x20, +  0x2b, 0x20, 0x28, 0x31, 0x2e, 0x35, 0x2f, 0x32, 0x35, 0x35, 0x2e, 0x30, +  0x29, 0x29, 0x20, 0x3c, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, +  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, +  0x64, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, +  0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, +  0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x70, 0x61, +  0x6c, 0x65, 0x74, 0x74, 0x65, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, +  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, +  0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; + diff --git a/pacc/hlsl/Makefile b/pacc/hlsl/Makefile new file mode 100644 index 0000000..7cd2f51 --- /dev/null +++ b/pacc/hlsl/Makefile @@ -0,0 +1,15 @@ +INCS:=copy.ps.inc color.ps.inc color_trans.ps.inc key.ps.inc fill.ps.inc font.ps.inc blit.vs.inc +FXC:=env WINEDEBUG=-all wine $(HOME)/hlsl/fxc/fxc +all:	$(INCS) + +%.inc:	%.inc.tmp +	dos2unix < $< | sed -e 's/^const BYTE g_/static const BYTE /' -e '$$a\\' > $@ + +%.vs.inc.tmp: %.vs.hlsl +	$(FXC) /nologo /O3 /Tvs_2_0 /E$(basename $(basename $<)) /Fh $@ $< + +%.ps.inc.tmp: %.ps.hlsl +	$(FXC) /nologo /O3 /Tps_2_0 /E$(basename $(basename $<)) /Fh $@ $< + +clean: +	rm -f $(INCS) diff --git a/pacc/hlsl/blit.vs.hlsl b/pacc/hlsl/blit.vs.hlsl new file mode 100644 index 0000000..ea4c18d --- /dev/null +++ b/pacc/hlsl/blit.vs.hlsl @@ -0,0 +1,17 @@ +struct vsinput { +  float4 coord : POSITION; +}; + +struct fsinput { +  float4 coord : POSITION; +  float4 texcoord : TEXCOORD; +}; + +float2 offset: register(c0); + +fsinput blit(vsinput input) { +  fsinput output; +  output.coord = float4(input.coord.xy + offset, 0.0, 1.0); +  output.texcoord = float4(input.coord.zw, 0.0, 1.0); +  return output; +} diff --git a/pacc/hlsl/blit.vs.inc b/pacc/hlsl/blit.vs.inc new file mode 100644 index 0000000..a2c4a64 --- /dev/null +++ b/pacc/hlsl/blit.vs.inc @@ -0,0 +1,71 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tvs_2_0 /Eblit /Fh blit.vs.inc.tmp blit.vs.hlsl +// +// +// Parameters: +// +//   float2 offset; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   offset       c0       1 +// + +    vs_2_0 +    def c1, 0, 1, 0, 0 +    dcl_position v0 +    add oPos.xy, v0, c0 +    mov oPos.zw, c1.xyxy +    mad oT0, v0.zwzz, c1.yyxx, c1.xxxy + +// approximately 3 instruction slots used +#endif + +static const BYTE vs20_blit[] = +{ +      0,   2, 254, 255, 254, 255,  +     33,   0,  67,  84,  65,  66,  +     28,   0,   0,   0,  79,   0,  +      0,   0,   0,   2, 254, 255,  +      1,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +     72,   0,   0,   0,  48,   0,  +      0,   0,   2,   0,   0,   0,  +      1,   0,   2,   0,  56,   0,  +      0,   0,   0,   0,   0,   0,  +    111, 102, 102, 115, 101, 116,  +      0, 171,   1,   0,   3,   0,  +      1,   0,   2,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    118, 115,  95,  50,  95,  48,  +      0,  77, 105,  99, 114, 111,  +    115, 111, 102, 116,  32,  40,  +     82,  41,  32,  72,  76,  83,  +     76,  32,  83, 104,  97, 100,  +    101, 114,  32,  67, 111, 109,  +    112, 105, 108, 101, 114,  32,  +     57,  46,  50,  57,  46,  57,  +     53,  50,  46,  51,  49,  49,  +     49,   0,  81,   0,   0,   5,  +      1,   0,  15, 160,   0,   0,  +      0,   0,   0,   0, 128,  63,  +      0,   0,   0,   0,   0,   0,  +      0,   0,  31,   0,   0,   2,  +      0,   0,   0, 128,   0,   0,  +     15, 144,   2,   0,   0,   3,  +      0,   0,   3, 192,   0,   0,  +    228, 144,   0,   0, 228, 160,  +      1,   0,   0,   2,   0,   0,  +     12, 192,   1,   0,  68, 160,  +      4,   0,   0,   4,   0,   0,  +     15, 224,   0,   0, 174, 144,  +      1,   0,   5, 160,   1,   0,  +     64, 160, 255, 255,   0,   0 +}; + diff --git a/pacc/hlsl/color.ps.hlsl b/pacc/hlsl/color.ps.hlsl new file mode 100644 index 0000000..5111097 --- /dev/null +++ b/pacc/hlsl/color.ps.hlsl @@ -0,0 +1,23 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); +sampler tex: register(s1); +float uni_color: register(c0); + +psoutput color(psinput input) { +  psoutput output; +  float index = tex2D(tex, input.texcoord.xy).r; +  if (index > (0.5/255.0)) { +    index = uni_color; +  } else { +    index = 0.5 / 256.0; +  } +  output.fragcolor = tex1D(palette, index); +  return output; +} diff --git a/pacc/hlsl/color.ps.inc b/pacc/hlsl/color.ps.inc new file mode 100644 index 0000000..5cd1a17 --- /dev/null +++ b/pacc/hlsl/color.ps.inc @@ -0,0 +1,106 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Ecolor /Fh color.ps.inc.tmp color.ps.hlsl +// +// +// Parameters: +// +//   sampler2D palette; +//   sampler2D tex; +//   float uni_color; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   uni_color    c0       1 +//   palette      s0       1 +//   tex          s1       1 +// + +    ps_2_0 +    def c1, 0.00196078443, 0.001953125, 0, 0 +    dcl t0.xy +    dcl_2d s0 +    dcl_2d s1 +    texld r0, t0, s1 +    add r0.x, -r0.x, c1.x +    mov r0.y, c1.y +    cmp r0.xy, r0.x, r0.y, c0.x +    texld r0, r0, s0 +    mov oC0, r0 + +// approximately 6 instruction slots used (2 texture, 4 arithmetic) +#endif + +static const BYTE ps20_color[] = +{ +      0,   2, 255, 255, 254, 255,  +     55,   0,  67,  84,  65,  66,  +     28,   0,   0,   0, 167,   0,  +      0,   0,   0,   2, 255, 255,  +      3,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +    160,   0,   0,   0,  88,   0,  +      0,   0,   3,   0,   0,   0,  +      1,   0,   2,   0,  96,   0,  +      0,   0,   0,   0,   0,   0,  +    112,   0,   0,   0,   3,   0,  +      1,   0,   1,   0,   6,   0,  +    116,   0,   0,   0,   0,   0,  +      0,   0, 132,   0,   0,   0,  +      2,   0,   0,   0,   1,   0,  +      2,   0, 144,   0,   0,   0,  +      0,   0,   0,   0, 112,  97,  +    108, 101, 116, 116, 101,   0,  +      4,   0,  12,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 116, 101,  +    120,   0,   4,   0,  12,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    117, 110, 105,  95,  99, 111,  +    108, 111, 114,   0, 171, 171,  +      0,   0,   3,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 112, 115,  +     95,  50,  95,  48,   0,  77,  +    105,  99, 114, 111, 115, 111,  +    102, 116,  32,  40,  82,  41,  +     32,  72,  76,  83,  76,  32,  +     83, 104,  97, 100, 101, 114,  +     32,  67, 111, 109, 112, 105,  +    108, 101, 114,  32,  57,  46,  +     50,  57,  46,  57,  53,  50,  +     46,  51,  49,  49,  49,   0,  +     81,   0,   0,   5,   1,   0,  +     15, 160, 129, 128,   0,  59,  +      0,   0,   0,  59,   0,   0,  +      0,   0,   0,   0,   0,   0,  +     31,   0,   0,   2,   0,   0,  +      0, 128,   0,   0,   3, 176,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   0,   8,  15, 160,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   1,   8,  15, 160,  +     66,   0,   0,   3,   0,   0,  +     15, 128,   0,   0, 228, 176,  +      1,   8, 228, 160,   2,   0,  +      0,   3,   0,   0,   1, 128,  +      0,   0,   0, 129,   1,   0,  +      0, 160,   1,   0,   0,   2,  +      0,   0,   2, 128,   1,   0,  +     85, 160,  88,   0,   0,   4,  +      0,   0,   3, 128,   0,   0,  +      0, 128,   0,   0,  85, 128,  +      0,   0,   0, 160,  66,   0,  +      0,   3,   0,   0,  15, 128,  +      0,   0, 228, 128,   0,   8,  +    228, 160,   1,   0,   0,   2,  +      0,   8,  15, 128,   0,   0,  +    228, 128, 255, 255,   0,   0 +}; + diff --git a/pacc/hlsl/color_trans.ps.hlsl b/pacc/hlsl/color_trans.ps.hlsl new file mode 100644 index 0000000..00999fd --- /dev/null +++ b/pacc/hlsl/color_trans.ps.hlsl @@ -0,0 +1,19 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); +sampler tex: register(s1); +float uni_color: register(c0); + +psoutput color_trans(psinput input) { +  psoutput output; +  float index = tex2D(tex, input.texcoord.xy).r; +  if (index < (0.5/255.0)) discard; +  output.fragcolor = tex1D(palette, uni_color); +  return output; +} diff --git a/pacc/hlsl/color_trans.ps.inc b/pacc/hlsl/color_trans.ps.inc new file mode 100644 index 0000000..6df66f8 --- /dev/null +++ b/pacc/hlsl/color_trans.ps.inc @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Ecolor_trans /Fh color_trans.ps.inc.tmp +//    color_trans.ps.hlsl +// +// +// Parameters: +// +//   sampler2D palette; +//   sampler2D tex; +//   float uni_color; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   uni_color    c0       1 +//   palette      s0       1 +//   tex          s1       1 +// + +    ps_2_0 +    def c1, -0.00196078443, -0, -1, 0 +    dcl t0.xy +    dcl_2d s0 +    dcl_2d s1 +    texld r0, t0, s1 +    add r0.x, r0.x, c1.x +    cmp r0, r0.x, c1.y, c1.z +    texkill r0 +    mov r0.xy, c0.x +    texld r0, r0, s0 +    mov oC0, r0 + +// approximately 7 instruction slots used (2 texture, 5 arithmetic) +#endif + +static const BYTE ps20_color_trans[] = +{ +      0,   2, 255, 255, 254, 255,  +     55,   0,  67,  84,  65,  66,  +     28,   0,   0,   0, 167,   0,  +      0,   0,   0,   2, 255, 255,  +      3,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +    160,   0,   0,   0,  88,   0,  +      0,   0,   3,   0,   0,   0,  +      1,   0,   2,   0,  96,   0,  +      0,   0,   0,   0,   0,   0,  +    112,   0,   0,   0,   3,   0,  +      1,   0,   1,   0,   6,   0,  +    116,   0,   0,   0,   0,   0,  +      0,   0, 132,   0,   0,   0,  +      2,   0,   0,   0,   1,   0,  +      2,   0, 144,   0,   0,   0,  +      0,   0,   0,   0, 112,  97,  +    108, 101, 116, 116, 101,   0,  +      4,   0,  12,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 116, 101,  +    120,   0,   4,   0,  12,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    117, 110, 105,  95,  99, 111,  +    108, 111, 114,   0, 171, 171,  +      0,   0,   3,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 112, 115,  +     95,  50,  95,  48,   0,  77,  +    105,  99, 114, 111, 115, 111,  +    102, 116,  32,  40,  82,  41,  +     32,  72,  76,  83,  76,  32,  +     83, 104,  97, 100, 101, 114,  +     32,  67, 111, 109, 112, 105,  +    108, 101, 114,  32,  57,  46,  +     50,  57,  46,  57,  53,  50,  +     46,  51,  49,  49,  49,   0,  +     81,   0,   0,   5,   1,   0,  +     15, 160, 129, 128,   0, 187,  +      0,   0,   0, 128,   0,   0,  +    128, 191,   0,   0,   0,   0,  +     31,   0,   0,   2,   0,   0,  +      0, 128,   0,   0,   3, 176,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   0,   8,  15, 160,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   1,   8,  15, 160,  +     66,   0,   0,   3,   0,   0,  +     15, 128,   0,   0, 228, 176,  +      1,   8, 228, 160,   2,   0,  +      0,   3,   0,   0,   1, 128,  +      0,   0,   0, 128,   1,   0,  +      0, 160,  88,   0,   0,   4,  +      0,   0,  15, 128,   0,   0,  +      0, 128,   1,   0,  85, 160,  +      1,   0, 170, 160,  65,   0,  +      0,   1,   0,   0,  15, 128,  +      1,   0,   0,   2,   0,   0,  +      3, 128,   0,   0,   0, 160,  +     66,   0,   0,   3,   0,   0,  +     15, 128,   0,   0, 228, 128,  +      0,   8, 228, 160,   1,   0,  +      0,   2,   0,   8,  15, 128,  +      0,   0, 228, 128, 255, 255,  +      0,   0 +}; + diff --git a/pacc/hlsl/copy.ps.hlsl b/pacc/hlsl/copy.ps.hlsl new file mode 100644 index 0000000..df9d1eb --- /dev/null +++ b/pacc/hlsl/copy.ps.hlsl @@ -0,0 +1,18 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); +sampler tex: register(s1); + +psoutput copy(psinput input) { +  psoutput output; +  float index = tex2D(tex, input.texcoord.xy).r; +  float color = (index * 255.0 + 0.5) / 256.0; +  output.fragcolor = tex1D(palette, color); +  return output; +} diff --git a/pacc/hlsl/copy.ps.inc b/pacc/hlsl/copy.ps.inc new file mode 100644 index 0000000..16acf0a --- /dev/null +++ b/pacc/hlsl/copy.ps.inc @@ -0,0 +1,93 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Ecopy /Fh copy.ps.inc.tmp copy.ps.hlsl +// +// +// Parameters: +// +//   sampler2D palette; +//   sampler2D tex; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   palette      s0       1 +//   tex          s1       1 +// + +    ps_2_0 +    def c0, 255, 0.5, 0.00390625, 0 +    dcl t0.xy +    dcl_2d s0 +    dcl_2d s1 +    texld r0, t0, s1 +    mad r0.x, r0.x, c0.x, c0.y +    mul r0.xy, r0.x, c0.z +    texld r0, r0, s0 +    mov oC0, r0 + +// approximately 5 instruction slots used (2 texture, 3 arithmetic) +#endif + +static const BYTE ps20_copy[] = +{ +      0,   2, 255, 255, 254, 255,  +     43,   0,  67,  84,  65,  66,  +     28,   0,   0,   0, 119,   0,  +      0,   0,   0,   2, 255, 255,  +      2,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +    112,   0,   0,   0,  68,   0,  +      0,   0,   3,   0,   0,   0,  +      1,   0,   2,   0,  76,   0,  +      0,   0,   0,   0,   0,   0,  +     92,   0,   0,   0,   3,   0,  +      1,   0,   1,   0,   6,   0,  +     96,   0,   0,   0,   0,   0,  +      0,   0, 112,  97, 108, 101,  +    116, 116, 101,   0,   4,   0,  +     12,   0,   1,   0,   1,   0,  +      1,   0,   0,   0,   0,   0,  +      0,   0, 116, 101, 120,   0,  +      4,   0,  12,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 112, 115,  +     95,  50,  95,  48,   0,  77,  +    105,  99, 114, 111, 115, 111,  +    102, 116,  32,  40,  82,  41,  +     32,  72,  76,  83,  76,  32,  +     83, 104,  97, 100, 101, 114,  +     32,  67, 111, 109, 112, 105,  +    108, 101, 114,  32,  57,  46,  +     50,  57,  46,  57,  53,  50,  +     46,  51,  49,  49,  49,   0,  +     81,   0,   0,   5,   0,   0,  +     15, 160,   0,   0, 127,  67,  +      0,   0,   0,  63,   0,   0,  +    128,  59,   0,   0,   0,   0,  +     31,   0,   0,   2,   0,   0,  +      0, 128,   0,   0,   3, 176,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   0,   8,  15, 160,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   1,   8,  15, 160,  +     66,   0,   0,   3,   0,   0,  +     15, 128,   0,   0, 228, 176,  +      1,   8, 228, 160,   4,   0,  +      0,   4,   0,   0,   1, 128,  +      0,   0,   0, 128,   0,   0,  +      0, 160,   0,   0,  85, 160,  +      5,   0,   0,   3,   0,   0,  +      3, 128,   0,   0,   0, 128,  +      0,   0, 170, 160,  66,   0,  +      0,   3,   0,   0,  15, 128,  +      0,   0, 228, 128,   0,   8,  +    228, 160,   1,   0,   0,   2,  +      0,   8,  15, 128,   0,   0,  +    228, 128, 255, 255,   0,   0 +}; + diff --git a/pacc/hlsl/fill.ps.hlsl b/pacc/hlsl/fill.ps.hlsl new file mode 100644 index 0000000..9939553 --- /dev/null +++ b/pacc/hlsl/fill.ps.hlsl @@ -0,0 +1,15 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); + +psoutput fill(psinput input) { +  psoutput output; +  output.fragcolor = tex1D(palette, input.texcoord.x); +  return output; +} diff --git a/pacc/hlsl/fill.ps.inc b/pacc/hlsl/fill.ps.inc new file mode 100644 index 0000000..3fcc075 --- /dev/null +++ b/pacc/hlsl/fill.ps.inc @@ -0,0 +1,65 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Efill /Fh fill.ps.inc.tmp fill.ps.hlsl +// +// +// Parameters: +// +//   sampler2D palette; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   palette      s0       1 +// + +    ps_2_0 +    dcl t0.xy +    dcl_2d s0 +    texld r0, t0, s0 +    mov oC0, r0 + +// approximately 2 instruction slots used (1 texture, 1 arithmetic) +#endif + +static const BYTE ps20_fill[] = +{ +      0,   2, 255, 255, 254, 255,  +     33,   0,  67,  84,  65,  66,  +     28,   0,   0,   0,  79,   0,  +      0,   0,   0,   2, 255, 255,  +      1,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +     72,   0,   0,   0,  48,   0,  +      0,   0,   3,   0,   0,   0,  +      1,   0,   2,   0,  56,   0,  +      0,   0,   0,   0,   0,   0,  +    112,  97, 108, 101, 116, 116,  +    101,   0,   4,   0,  12,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    112, 115,  95,  50,  95,  48,  +      0,  77, 105,  99, 114, 111,  +    115, 111, 102, 116,  32,  40,  +     82,  41,  32,  72,  76,  83,  +     76,  32,  83, 104,  97, 100,  +    101, 114,  32,  67, 111, 109,  +    112, 105, 108, 101, 114,  32,  +     57,  46,  50,  57,  46,  57,  +     53,  50,  46,  51,  49,  49,  +     49,   0,  31,   0,   0,   2,  +      0,   0,   0, 128,   0,   0,  +      3, 176,  31,   0,   0,   2,  +      0,   0,   0, 144,   0,   8,  +     15, 160,  66,   0,   0,   3,  +      0,   0,  15, 128,   0,   0,  +    228, 176,   0,   8, 228, 160,  +      1,   0,   0,   2,   0,   8,  +     15, 128,   0,   0, 228, 128,  +    255, 255,   0,   0 +}; + diff --git a/pacc/hlsl/font.ps.hlsl b/pacc/hlsl/font.ps.hlsl new file mode 100644 index 0000000..406da2e --- /dev/null +++ b/pacc/hlsl/font.ps.hlsl @@ -0,0 +1,24 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); +sampler tex: register(s1); +float bg: register(c0); +float color: register(c1); + +psoutput font(psinput input) { +  psoutput output; +  float pixel = tex2D(tex, input.texcoord.xy).r; +  float index = color; +  if (pixel < 0.5) { +    if (bg < 0.5) discard; +    index = 0.5 / 256.0; +  } +  output.fragcolor = tex1D(palette, index); +  return output; +} diff --git a/pacc/hlsl/font.ps.inc b/pacc/hlsl/font.ps.inc new file mode 100644 index 0000000..2167cf7 --- /dev/null +++ b/pacc/hlsl/font.ps.inc @@ -0,0 +1,126 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Efont /Fh font.ps.inc.tmp font.ps.hlsl +// +// +// Parameters: +// +//   float bg; +//   float color; +//   sampler2D palette; +//   sampler2D tex; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   bg           c0       1 +//   color        c1       1 +//   palette      s0       1 +//   tex          s1       1 +// + +    ps_2_0 +    def c2, -0.5, -0, -1, 0.001953125 +    dcl t0.xy +    dcl_2d s0 +    dcl_2d s1 +    texld r0, t0, s1 +    add r0.x, r0.x, c2.x +    mov r1.xw, c2 +    add r0.y, r1.x, c0.x +    cmp r0.y, r0.y, c2.y, c2.z +    cmp r2, r0.x, c2.y, r0.y +    texkill r2 +    cmp r0.xy, r0.x, c1.x, r1.w +    texld r0, r0, s0 +    mov oC0, r0 + +// approximately 10 instruction slots used (2 texture, 8 arithmetic) +#endif + +static const BYTE ps20_font[] = +{ +      0,   2, 255, 255, 254, 255,  +     60,   0,  67,  84,  65,  66,  +     28,   0,   0,   0, 187,   0,  +      0,   0,   0,   2, 255, 255,  +      4,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +    180,   0,   0,   0, 108,   0,  +      0,   0,   2,   0,   0,   0,  +      1,   0,   2,   0, 112,   0,  +      0,   0,   0,   0,   0,   0,  +    128,   0,   0,   0,   2,   0,  +      1,   0,   1,   0,   6,   0,  +    112,   0,   0,   0,   0,   0,  +      0,   0, 134,   0,   0,   0,  +      3,   0,   0,   0,   1,   0,  +      2,   0, 144,   0,   0,   0,  +      0,   0,   0,   0, 160,   0,  +      0,   0,   3,   0,   1,   0,  +      1,   0,   6,   0, 164,   0,  +      0,   0,   0,   0,   0,   0,  +     98, 103,   0, 171,   0,   0,  +      3,   0,   1,   0,   1,   0,  +      1,   0,   0,   0,   0,   0,  +      0,   0,  99, 111, 108, 111,  +    114,   0, 112,  97, 108, 101,  +    116, 116, 101,   0, 171, 171,  +      4,   0,  12,   0,   1,   0,  +      1,   0,   1,   0,   0,   0,  +      0,   0,   0,   0, 116, 101,  +    120,   0,   4,   0,  12,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    112, 115,  95,  50,  95,  48,  +      0,  77, 105,  99, 114, 111,  +    115, 111, 102, 116,  32,  40,  +     82,  41,  32,  72,  76,  83,  +     76,  32,  83, 104,  97, 100,  +    101, 114,  32,  67, 111, 109,  +    112, 105, 108, 101, 114,  32,  +     57,  46,  50,  57,  46,  57,  +     53,  50,  46,  51,  49,  49,  +     49,   0,  81,   0,   0,   5,  +      2,   0,  15, 160,   0,   0,  +      0, 191,   0,   0,   0, 128,  +      0,   0, 128, 191,   0,   0,  +      0,  59,  31,   0,   0,   2,  +      0,   0,   0, 128,   0,   0,  +      3, 176,  31,   0,   0,   2,  +      0,   0,   0, 144,   0,   8,  +     15, 160,  31,   0,   0,   2,  +      0,   0,   0, 144,   1,   8,  +     15, 160,  66,   0,   0,   3,  +      0,   0,  15, 128,   0,   0,  +    228, 176,   1,   8, 228, 160,  +      2,   0,   0,   3,   0,   0,  +      1, 128,   0,   0,   0, 128,  +      2,   0,   0, 160,   1,   0,  +      0,   2,   1,   0,   9, 128,  +      2,   0, 228, 160,   2,   0,  +      0,   3,   0,   0,   2, 128,  +      1,   0,   0, 128,   0,   0,  +      0, 160,  88,   0,   0,   4,  +      0,   0,   2, 128,   0,   0,  +     85, 128,   2,   0,  85, 160,  +      2,   0, 170, 160,  88,   0,  +      0,   4,   2,   0,  15, 128,  +      0,   0,   0, 128,   2,   0,  +     85, 160,   0,   0,  85, 128,  +     65,   0,   0,   1,   2,   0,  +     15, 128,  88,   0,   0,   4,  +      0,   0,   3, 128,   0,   0,  +      0, 128,   1,   0,   0, 160,  +      1,   0, 255, 128,  66,   0,  +      0,   3,   0,   0,  15, 128,  +      0,   0, 228, 128,   0,   8,  +    228, 160,   1,   0,   0,   2,  +      0,   8,  15, 128,   0,   0,  +    228, 128, 255, 255,   0,   0 +}; + diff --git a/pacc/hlsl/key.ps.hlsl b/pacc/hlsl/key.ps.hlsl new file mode 100644 index 0000000..0ca9efd --- /dev/null +++ b/pacc/hlsl/key.ps.hlsl @@ -0,0 +1,20 @@ +struct psinput { +  float4 texcoord: TEXCOORD; +}; + +struct psoutput { +  float4 fragcolor: COLOR; +}; + +sampler palette: register(s0); +sampler tex: register(s1); +float uni_key: register(c0); +float color: register(c1); + +psoutput key(psinput input) { +  psoutput output; +  float index = tex2D(tex, input.texcoord.xy).r; +  if (index < (uni_key + (0.5/255.0)) || (uni_key + (1.5/255.0)) < index) discard; +  output.fragcolor = tex1D(palette, color); +  return output; +} diff --git a/pacc/hlsl/key.ps.inc b/pacc/hlsl/key.ps.inc new file mode 100644 index 0000000..63d51d8 --- /dev/null +++ b/pacc/hlsl/key.ps.inc @@ -0,0 +1,141 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +//   fxc /nologo /O3 /Tps_2_0 /Ekey /Fh key.ps.inc.tmp key.ps.hlsl +// +// +// Parameters: +// +//   float color; +//   sampler2D palette; +//   sampler2D tex; +//   float uni_key; +// +// +// Registers: +// +//   Name         Reg   Size +//   ------------ ----- ---- +//   uni_key      c0       1 +//   color        c1       1 +//   palette      s0       1 +//   tex          s1       1 +// + +    ps_2_0 +    def c2, 0.00196078443, 0, 1, 0.00588235306 +    dcl t0.xy +    dcl_2d s0 +    dcl_2d s1 +    texld r0, t0, s1 +    mov r1.xw, c2 +    add r0.y, r1.w, c0.x +    add r0.y, -r0.x, r0.y +    cmp r0.y, r0.y, c2.y, c2.z +    add r0.z, r1.x, c0.x +    add r0.x, -r0.z, r0.x +    cmp r0.x, r0.x, c2.y, c2.z +    add r0.x, r0.y, r0.x +    cmp r0, -r0.x, -c2.y, -c2.z +    texkill r0 +    mov r0.xy, c1.x +    texld r0, r0, s0 +    mov oC0, r0 + +// approximately 14 instruction slots used (2 texture, 12 arithmetic) +#endif + +static const BYTE ps20_key[] = +{ +      0,   2, 255, 255, 254, 255,  +     61,   0,  67,  84,  65,  66,  +     28,   0,   0,   0, 191,   0,  +      0,   0,   0,   2, 255, 255,  +      4,   0,   0,   0,  28,   0,  +      0,   0,   0, 129,   0,   0,  +    184,   0,   0,   0, 108,   0,  +      0,   0,   2,   0,   1,   0,  +      1,   0,   6,   0, 116,   0,  +      0,   0,   0,   0,   0,   0,  +    132,   0,   0,   0,   3,   0,  +      0,   0,   1,   0,   2,   0,  +    140,   0,   0,   0,   0,   0,  +      0,   0, 156,   0,   0,   0,  +      3,   0,   1,   0,   1,   0,  +      6,   0, 160,   0,   0,   0,  +      0,   0,   0,   0, 176,   0,  +      0,   0,   2,   0,   0,   0,  +      1,   0,   2,   0, 116,   0,  +      0,   0,   0,   0,   0,   0,  +     99, 111, 108, 111, 114,   0,  +    171, 171,   0,   0,   3,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    112,  97, 108, 101, 116, 116,  +    101,   0,   4,   0,  12,   0,  +      1,   0,   1,   0,   1,   0,  +      0,   0,   0,   0,   0,   0,  +    116, 101, 120,   0,   4,   0,  +     12,   0,   1,   0,   1,   0,  +      1,   0,   0,   0,   0,   0,  +      0,   0, 117, 110, 105,  95,  +    107, 101, 121,   0, 112, 115,  +     95,  50,  95,  48,   0,  77,  +    105,  99, 114, 111, 115, 111,  +    102, 116,  32,  40,  82,  41,  +     32,  72,  76,  83,  76,  32,  +     83, 104,  97, 100, 101, 114,  +     32,  67, 111, 109, 112, 105,  +    108, 101, 114,  32,  57,  46,  +     50,  57,  46,  57,  53,  50,  +     46,  51,  49,  49,  49,   0,  +     81,   0,   0,   5,   2,   0,  +     15, 160, 129, 128,   0,  59,  +      0,   0,   0,   0,   0,   0,  +    128,  63, 193, 192, 192,  59,  +     31,   0,   0,   2,   0,   0,  +      0, 128,   0,   0,   3, 176,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   0,   8,  15, 160,  +     31,   0,   0,   2,   0,   0,  +      0, 144,   1,   8,  15, 160,  +     66,   0,   0,   3,   0,   0,  +     15, 128,   0,   0, 228, 176,  +      1,   8, 228, 160,   1,   0,  +      0,   2,   1,   0,   9, 128,  +      2,   0, 228, 160,   2,   0,  +      0,   3,   0,   0,   2, 128,  +      1,   0, 255, 128,   0,   0,  +      0, 160,   2,   0,   0,   3,  +      0,   0,   2, 128,   0,   0,  +      0, 129,   0,   0,  85, 128,  +     88,   0,   0,   4,   0,   0,  +      2, 128,   0,   0,  85, 128,  +      2,   0,  85, 160,   2,   0,  +    170, 160,   2,   0,   0,   3,  +      0,   0,   4, 128,   1,   0,  +      0, 128,   0,   0,   0, 160,  +      2,   0,   0,   3,   0,   0,  +      1, 128,   0,   0, 170, 129,  +      0,   0,   0, 128,  88,   0,  +      0,   4,   0,   0,   1, 128,  +      0,   0,   0, 128,   2,   0,  +     85, 160,   2,   0, 170, 160,  +      2,   0,   0,   3,   0,   0,  +      1, 128,   0,   0,  85, 128,  +      0,   0,   0, 128,  88,   0,  +      0,   4,   0,   0,  15, 128,  +      0,   0,   0, 129,   2,   0,  +     85, 161,   2,   0, 170, 161,  +     65,   0,   0,   1,   0,   0,  +     15, 128,   1,   0,   0,   2,  +      0,   0,   3, 128,   1,   0,  +      0, 160,  66,   0,   0,   3,  +      0,   0,  15, 128,   0,   0,  +    228, 128,   0,   8, 228, 160,  +      1,   0,   0,   2,   0,   8,  +     15, 128,   0,   0, 228, 128,  +    255, 255,   0,   0 +}; + diff --git a/pacc/pacc-d3d9.c b/pacc/pacc-d3d9.c new file mode 100644 index 0000000..21f3210 --- /dev/null +++ b/pacc/pacc-d3d9.c @@ -0,0 +1,633 @@ +#include "pacc-win.h" +#include <d3d9.h> +#include <stdlib.h> +#include <stdatomic.h> +#include <stdint.h> +#include <stdio.h> + +#include "hlsl/blit.vs.inc" +#include "hlsl/copy.ps.inc" +#include "hlsl/color.ps.inc" +#include "hlsl/color_trans.ps.inc" + +struct pacc_ctx { +  int w, h; +  uint8_t pal[256*3]; +  bool pal_changed; +  uint8_t clearpal; +  uint8_t color; +  uint8_t color_changed; +  bool render_enabled; +  enum pacc_mode curr_mode; +  atomic_bool killthread; +  HWND hwnd; +  HMODULE d3d9m; +  IDirect3D9 *d3d9; +  IDirect3DDevice9 *d3d9d; +  IDirect3DTexture9 *tex_pal; +  IDirect3DVertexDeclaration9 *vdecl; +  IDirect3DVertexShader9 *vs; +  IDirect3DPixelShader9 *ps_modes[pacc_mode_count]; +  IDirect3DStateBlock9 *state_common; +  IDirect3DStateBlock9 *state_modes[pacc_mode_count]; +  pacc_rendercb *rendercb; +  void *renderptr; +  HANDLE renderthread; +  HANDLE rendermtx; +}; + +struct pacc_buf { +  IDirect3DVertexBuffer9 *buf_obj; +  float *buf; +  struct pacc_tex *tex; +  int len; +  int buflen; +  int bufobjlen; +  bool changed; +}; + +struct pacc_tex { +  int w, h; +  bool changed; +  atomic_flag flag; +  IDirect3DTexture9 *tex_obj; +  uint8_t *buf; +}; + +enum { +  PACC_BUF_DEF_LEN = 32, +  PRINTBUFLEN = 160, +}; + +static void pacc_buf_delete(struct pacc_buf *pb) { +  if (pb) { +    if (pb->buf_obj) pb->buf_obj->lpVtbl->Release(pb->buf_obj); +    free(pb->buf); +    free(pb); +  } +} + +static struct pacc_buf *pacc_gen_buf( +    struct pacc_ctx *pc, struct pacc_tex *pt, enum pacc_buf_mode mode) { +  struct pacc_buf *pb = malloc(sizeof(*pb)); +  if (!pb) goto err; +  *pb = (struct pacc_buf) { +    .buflen = PACC_BUF_DEF_LEN, +    .bufobjlen = PACC_BUF_DEF_LEN, +    .tex = pt, +  }; +  pb->buf = malloc(sizeof(*pb->buf) * pb->buflen); +  if (!pb->buf) goto err; +  HRESULT res; +  res = pc->d3d9d->lpVtbl->CreateVertexBuffer( +      pc->d3d9d, +      sizeof(*pb->buf) * pb->buflen, +      D3DUSAGE_DYNAMIC, +      0, +      D3DPOOL_DEFAULT, +      &pb->buf_obj, +      0); +  if (res != D3D_OK) goto err; +  return pb; +err: +  MessageBox(pc->hwnd, L"Hello", L"HI", 0); +  pacc_buf_delete(pb); +  return 0; +} + +static bool buf_reserve(struct pacc_buf *pb, int len) { +  if (pb->len + len > pb->buflen) { +    int newlen = pb->buflen; +    while (pb->len + len > newlen) newlen *= 2; +    float *newbuf = realloc(pb->buf, newlen * sizeof(pb->buf[0])); +    if (!newbuf) return false; +    pb->buflen = newlen; +    pb->buf = newbuf; +  } +  return true; +} + +static void pacc_calc_scale(float *ret, int w, int h, int wdest, int hdest) { +  ret[0] = ((float)w) / wdest; +  ret[1] = ((float)h) / hdest; +} + +static void pacc_calc_off_tex(float *ret, +                                     int tw, int th, int xsrc, int ysrc) { +  ret[0] = ((float)xsrc) / tw; +  ret[1] = ((float)ysrc) / th; +} + +static void pacc_calc_off( +    float *ret, int xdest, int ydest, int w, int h, int wdest, int hdest) { +  ret[0] = ((float)(xdest * 2 + w - wdest)) / wdest; +  ret[1] = ((float)(ydest * 2 + h - hdest)) / hdest; +} + +static void pacc_buf_rect_off( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, int w, int h, int xoff, int yoff) { +  float scale[2]; +  float off[2]; +  float tscale[2]; +  float toff[2]; +  pacc_calc_off(off, x, y, w, h, pc->w, pc->h); +  pacc_calc_scale(scale, w, h, pc->w, pc->h); +  pacc_calc_off_tex(toff, pb->tex->w, pb->tex->h, xoff, yoff); +  pacc_calc_scale(tscale, w, h, pb->tex->w, pb->tex->h); +  float coord[16] = { +    -1.0f * scale[0] + off[0], -1.0f * scale[1] - off[1], +     0.0f * tscale[0] + toff[0],  1.0f * tscale[1] + toff[1], + +    -1.0f * scale[0] + off[0],  1.0f * scale[1] - off[1], +     0.0f * tscale[0] + toff[0],  0.0f * tscale[1] + toff[1], + +     1.0f * scale[0] + off[0], -1.0f * scale[1] - off[1], +     1.0f * tscale[0] + toff[0],  1.0f * tscale[1] + toff[1], + +     1.0f * scale[0] + off[0],  1.0f * scale[1] - off[1], +     1.0f * tscale[0] + toff[0],  0.0f * tscale[1] + toff[1], +  }; +  if (!buf_reserve(pb, 24)) return; +  int indices[6] = {0, 1, 2, 2, 1, 3}; +  for (int i = 0; i < 6; i++) { +    for (int j = 0; j < 4; j++) { +      pb->buf[pb->len+i*4+j] = coord[indices[i]*4+j]; +    } +  } +  pb->len += 24; +  pb->changed = true; +} + +static void pacc_buf_vprintf( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, const char *fmt, va_list ap) { +  uint8_t printbuf[PRINTBUFLEN+1]; +  vsnprintf((char *)printbuf, sizeof(printbuf), fmt, ap); +  int len = strlen((const char *)printbuf); +  float scale[2]; +  float off[2]; +  int w = pb->tex->w / 256; +  int h = pb->tex->h; +  pacc_calc_scale(scale, w, h, pc->w, pc->h); +  pacc_calc_off(off, x, y, w, h, pc->w, pc->h); +  if (!buf_reserve(pb, len*24)) return; +  float *coords = pb->buf + pb->len; +  for (int i = 0; i < len; i++) { +    coords[24*i+0*4+0]                      = (-1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+0*4+1]                      = -1.0f * scale[1] - off[1]; +    coords[24*i+1*4+0] = coords[24*i+4*4+0] = (-1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+1*4+1] = coords[24*i+4*4+1] = 1.0f * scale[1] - off[1]; +    coords[24*i+2*4+0] = coords[24*i+3*4+0] = (1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+2*4+1] = coords[24*i+3*4+1] = -1.0f * scale[1] - off[1]; +    coords[24*i+5*4+0]                      = (1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+5*4+1]                      = 1.0f * scale[1] - off[1]; +    coords[24*i+0*4+2]                      = ((float)printbuf[i]) / 256.0f; +    coords[24*i+0*4+3]                      = 1.0f; +    coords[24*i+1*4+2] = coords[24*i+4*4+2] = ((float)printbuf[i]) / 256.0f; +    coords[24*i+1*4+3] = coords[24*i+4*4+3] = 0.0f; +    coords[24*i+2*4+2] = coords[24*i+3*4+2] = ((float)(printbuf[i]+1)) / 256.0f; +    coords[24*i+2*4+3] = coords[24*i+3*4+3] = 1.0f; +    coords[24*i+5*4+2]                      = ((float)(printbuf[i]+1)) / 256.0f; +    coords[24*i+5*4+3]                      = 0.0f; +  } +  pb->len += len * 24; +  pb->changed = true; +} + +static void pacc_buf_printf( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, const char *fmt, ...) { +  va_list ap; +  va_start(ap, fmt); +  pacc_buf_vprintf(pc, pb, x, y, fmt, ap); +  va_end(ap); +} + +static void pacc_buf_rect( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, int w, int h) { +  pacc_buf_rect_off(pc, pb, x, y, w, h, 0, 0); +} + +static void pacc_buf_clear(struct pacc_buf *pb) { +  pb->len = 0; +  pb->changed = true; +} + +static void pacc_palette(struct pacc_ctx *pc, const uint8_t *rgb, int colors) { +  memcpy(pc->pal, rgb, colors*3); +  pc->pal_changed = true; +} + +static void pacc_color(struct pacc_ctx *pc, uint8_t pal) { +  pc->color = pal; +  pc->color_changed = true; +} + +static void pacc_begin_clear(struct pacc_ctx *pc) { +  if (pc->pal_changed) { +    D3DLOCKED_RECT lockrect; +    if (SUCCEEDED(pc->tex_pal->lpVtbl->LockRect( +            pc->tex_pal, 0, &lockrect, 0, D3DLOCK_DISCARD))) { +      uint32_t *palpixel = lockrect.pBits; +      for (int i = 0; i < 256; i++) { +        palpixel[i] = +          ((uint32_t)pc->pal[i*3+0]) << 16 | +          ((uint32_t)pc->pal[i*3+1]) << 8 | +          pc->pal[i*3+2]; +      } +      pc->tex_pal->lpVtbl->UnlockRect( +          pc->tex_pal, 0); +    } +    pc->pal_changed = false; +  } +  pc->d3d9d->lpVtbl->Clear( +      pc->d3d9d, +      0, 0, D3DCLEAR_TARGET, +      D3DCOLOR_RGBA( +        pc->pal[0], pc->pal[1], pc->pal[2], 0xff +        ), 1.0, 0); +  pc->state_common->lpVtbl->Apply(pc->state_common); +  float offsets[4] = { +    -0.5f / pc->w, 0.5f / pc->h, 0.0f, 0.0f, +  }; +  pc->d3d9d->lpVtbl->SetVertexShaderConstantF( +      pc->d3d9d, +      0, offsets, 1); +  pc->curr_mode = pacc_mode_count; +} + +static void pacc_draw(struct pacc_ctx *pc, struct pacc_buf *pb, enum pacc_mode mode) { +  if (mode >= pacc_mode_count) return; +  if (pc->curr_mode != mode) { +    pc->state_modes[mode]->lpVtbl->Apply(pc->state_modes[mode]); +    pc->curr_mode = mode; +  } +  if (mode != pacc_mode_copy && pc->color_changed) { +    float fbuf[4] = {pc->color / 255.f}; +    pc->d3d9d->lpVtbl->SetPixelShaderConstantF(pc->d3d9d, 0, fbuf, 1); +    pc->color_changed = false; +  } +  if (pb->tex->changed) { +    D3DLOCKED_RECT lockrect; +    if (SUCCEEDED(pb->tex->tex_obj->lpVtbl->LockRect( +            pb->tex->tex_obj, 0, &lockrect, 0, 0))) { +      while (atomic_flag_test_and_set_explicit(&pb->tex->flag, memory_order_acquire)); +      for (int y = 0; y < pb->tex->h; y++) { +        memcpy( +            (char *)lockrect.pBits + lockrect.Pitch * y, +            pb->tex->buf + pb->tex->w * y, +            pb->tex->w); +      } +      atomic_flag_clear_explicit(&pb->tex->flag, memory_order_release); +      pb->tex->tex_obj->lpVtbl->UnlockRect( +          pb->tex->tex_obj, 0); +    } +    pb->tex->changed = false; +  } +  if (pb->changed) { +    if (pb->buflen > pb->bufobjlen) { +      IDirect3DVertexBuffer9 *newbufobj; +      HRESULT res; +      res = pc->d3d9d->lpVtbl->CreateVertexBuffer( +          pc->d3d9d, +          sizeof(*pb->buf) * pb->buflen, +          D3DUSAGE_DYNAMIC, +          0, +          D3DPOOL_DEFAULT, +          &newbufobj, +          0); +      if (res != D3D_OK) return; +      pb->buf_obj->lpVtbl->Release(pb->buf_obj); +      pb->buf_obj = newbufobj; +      pb->bufobjlen = pb->buflen; +    } +    float *objbuf; +    if (SUCCEEDED(pb->buf_obj->lpVtbl->Lock( +            pb->buf_obj, +            0, sizeof(float)*pb->len, +            (void **)&objbuf, +            D3DLOCK_DISCARD))) { +      memcpy(objbuf, pb->buf, pb->len*sizeof(pb->buf[0])); +      pb->buf_obj->lpVtbl->Unlock(pb->buf_obj); +    } +    pb->changed = false; +  } +  DWORD texaddru, texaddrv; +  if (pb->tex->w & (pb->tex->w - 1)) { +    texaddru = D3DTADDRESS_CLAMP; +  } else { +    texaddru = D3DTADDRESS_WRAP; +  } +  if (pb->tex->h & (pb->tex->h - 1)) { +    texaddrv = D3DTADDRESS_CLAMP; +  } else { +    texaddrv = D3DTADDRESS_WRAP; +  } +  pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 1, D3DSAMP_ADDRESSU, texaddru); +  pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 1, D3DSAMP_ADDRESSV, texaddrv); +  pc->d3d9d->lpVtbl->SetTexture( +      pc->d3d9d, 1, (IDirect3DBaseTexture9 *)pb->tex->tex_obj); +  pc->d3d9d->lpVtbl->SetStreamSource( +      pc->d3d9d, +      0, +      pb->buf_obj, +      0, 4*sizeof(float)); +  pc->d3d9d->lpVtbl->DrawPrimitive( +      pc->d3d9d, +      D3DPT_TRIANGLELIST, +      0, pb->len/(3*4)); +} + +static uint8_t *pacc_tex_lock(struct pacc_tex *pt) { +  while (atomic_flag_test_and_set_explicit(&pt->flag, memory_order_acquire)); +  return pt->buf; +} + +static void pacc_tex_unlock(struct pacc_tex *pt) { +  pt->changed = true; +  atomic_flag_clear_explicit(&pt->flag, memory_order_release); +} + +static void pacc_tex_delete(struct pacc_tex *pt) { +  if (pt) { +    if (pt->tex_obj) pt->tex_obj->lpVtbl->Release(pt->tex_obj); +    free(pt->buf); +    free(pt); +  } +} + +static struct pacc_tex *pacc_gen_tex(struct pacc_ctx *pc, int w, int h) { +  struct pacc_tex *pt = malloc(sizeof(*pt)); +  if (!pt) goto err; +  *pt = (struct pacc_tex) { +    .w = w, +    .h = h, +    .buf = calloc(w*h, 1), +  }; +  if (!pt->buf) goto err; +  atomic_flag_clear_explicit(&pt->flag, memory_order_release); +  HRESULT res; +  res = pc->d3d9d->lpVtbl->CreateTexture( +      pc->d3d9d, +      w, h, +      1, +      D3DUSAGE_DYNAMIC, +      D3DFMT_L8, +      D3DPOOL_DEFAULT, +      &pt->tex_obj, +      0); +  if (res != D3D_OK) goto err; +  return pt; +err: +  pacc_tex_delete(pt); +  return 0; +} + +static void pacc_delete(struct pacc_ctx *pc) { +  if (pc) { +    if (pc->renderthread) { +      atomic_store_explicit(&pc->killthread, true, memory_order_relaxed); +      WaitForSingleObject(pc->renderthread, INFINITE); +    } +    for (int i = 0; i < pacc_mode_count; i++) { +      if (pc->ps_modes[i]) pc->ps_modes[i]->lpVtbl->Release(pc->ps_modes[i]); +      if (pc->state_modes[i]) pc->state_modes[i]->lpVtbl->Release(pc->state_modes[i]); +    } +    if (pc->state_common) pc->state_common->lpVtbl->Release(pc->state_common); +    if (pc->vs) pc->vs->lpVtbl->Release(pc->vs); +    if (pc->vdecl) pc->vdecl->lpVtbl->Release(pc->vdecl); +    if (pc->tex_pal) pc->tex_pal->lpVtbl->Release(pc->tex_pal); +    if (pc->d3d9d) pc->d3d9d->lpVtbl->Release(pc->d3d9d); +    if (pc->d3d9) pc->d3d9->lpVtbl->Release(pc->d3d9); +    if (pc->d3d9m) FreeLibrary(pc->d3d9m); +    if (pc->rendermtx) CloseHandle(pc->rendermtx); +    free(pc); +  } +} + +static DWORD WINAPI pacc_renderproc(void *ptr) { +  struct pacc_ctx *pc = ptr; +  while (!atomic_load_explicit(&pc->killthread, memory_order_relaxed)) { +    if (WaitForSingleObject(pc->rendermtx, INFINITE) == WAIT_OBJECT_0) { +      if (SUCCEEDED(pc->d3d9d->lpVtbl->BeginScene(pc->d3d9d))) { +        if (pc->render_enabled) { +          pc->rendercb(pc->renderptr); +        } else { +          pc->d3d9d->lpVtbl->Clear( +              pc->d3d9d, +              0, 0, D3DCLEAR_TARGET, +              D3DCOLOR_RGBA(0x00, 0x00, 0x00, 0xff), +              1.0, 0); +        } +        pc->d3d9d->lpVtbl->EndScene(pc->d3d9d); +        pc->d3d9d->lpVtbl->Present(pc->d3d9d, 0, 0, 0, 0); +      } +      ReleaseMutex(pc->rendermtx); +    } +  } +  return 0; +} + +static void pacc_renderctrl(struct pacc_ctx *pc, bool enable) { +  while (WaitForSingleObject(pc->rendermtx, INFINITE) != WAIT_OBJECT_0); +  pc->render_enabled = enable; +  ReleaseMutex(pc->rendermtx); +} + +static struct pacc_vtable pacc_d3d9_vtable = { +  .pacc_delete = pacc_delete, +  .gen_buf = pacc_gen_buf, +  .gen_tex = pacc_gen_tex, +  .buf_delete = pacc_buf_delete, +  .tex_lock = pacc_tex_lock, +  .tex_unlock = pacc_tex_unlock, +  .tex_delete = pacc_tex_delete, +  .buf_rect = pacc_buf_rect, +  .buf_rect_off = pacc_buf_rect_off, +  .buf_vprintf = pacc_buf_vprintf, +  .buf_printf = pacc_buf_printf, +  .buf_clear = pacc_buf_clear, +  .palette = pacc_palette, +  .color = pacc_color, +  .begin_clear = pacc_begin_clear, +  .draw = pacc_draw, +}; + +struct pacc_win_vtable pacc_win_vtable = { +  .renderctrl = pacc_renderctrl, +}; + +struct pacc_ctx *pacc_init_d3d9( +    HWND hwnd, +    pacc_rendercb *rendercb, void *renderptr, +    struct pacc_vtable *vt, struct pacc_win_vtable *winvt) { +  struct pacc_ctx *pc = malloc(sizeof(*pc)); +  if (!pc) goto err; +  RECT wr; +  if (!GetClientRect(hwnd, &wr)) goto err; +  *pc = (struct pacc_ctx) { +    .w = wr.right - wr.left, +    .h = wr.bottom - wr.top, +    .hwnd = hwnd, +    .rendercb = rendercb, +    .renderptr = renderptr, +  }; +  atomic_init(&pc->killthread, false); +  pc->rendermtx = CreateMutex(0, FALSE, 0); +  if (!pc->rendermtx) goto err; +  pc->d3d9m = LoadLibrary(L"d3d9"); +  if (!pc->d3d9m) goto err; +  IDirect3D9 * WINAPI (*d3d9create)(UINT) = (IDirect3D9 * WINAPI (*)(UINT))GetProcAddress(pc->d3d9m, "Direct3DCreate9"); +  if (!d3d9create) goto err; +  pc->d3d9 = d3d9create(D3D_SDK_VERSION); +  if (!pc->d3d9) goto err; + +  D3DCAPS9 dcaps; +  HRESULT res; +  res = pc->d3d9->lpVtbl->GetDeviceCaps( +      pc->d3d9, +      D3DADAPTER_DEFAULT, +      D3DDEVTYPE_HAL, +      &dcaps); +  if (res != D3D_OK) goto err; + +  D3DMULTISAMPLE_TYPE ms; +#ifdef PACC_DEBUG_MSAA +  ms = D3DMULTISAMPLE_8_SAMPLES; +#else +  ms = D3DMULTISAMPLE_NONE; +#endif +  D3DPRESENT_PARAMETERS dp = { +    .MultiSampleType = ms, +    .BackBufferWidth = pc->w * 2, +    .BackBufferHeight = pc->h * 2, +    .SwapEffect = D3DSWAPEFFECT_DISCARD, +    .hDeviceWindow = pc->hwnd, +    .Windowed = TRUE, +  }; +  DWORD behavior = D3DCREATE_MULTITHREADED; +  /* from SDL_renderer_d3d.c +     fallback to software vertex processing when hardware vertex processing not available +   */ +  behavior |= (dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? +    D3DCREATE_HARDWARE_VERTEXPROCESSING : +    D3DCREATE_SOFTWARE_VERTEXPROCESSING; +  res = pc->d3d9->lpVtbl->CreateDevice( +      pc->d3d9, +      D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, +      0, +      behavior, +      &dp, &pc->d3d9d); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->CreateTexture( +      pc->d3d9d, +      256, 1, +      1, +      D3DUSAGE_DYNAMIC, +      D3DFMT_X8R8G8B8, +      D3DPOOL_DEFAULT, +      &pc->tex_pal, +      0); +  if (res != D3D_OK) goto err; + +  D3DVERTEXELEMENT9 vertexdecls[] = { +    { +      .Stream = 0, +      .Offset = 0, +      .Type = D3DDECLTYPE_FLOAT4, +      .Method = D3DDECLMETHOD_DEFAULT, +      .Usage = D3DDECLUSAGE_POSITION, +      .UsageIndex = 0, +    }, +    D3DDECL_END() +  }; +  res = pc->d3d9d->lpVtbl->CreateVertexDeclaration( +      pc->d3d9d, +      vertexdecls, +      &pc->vdecl); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->CreateVertexShader( +      pc->d3d9d, +      (const DWORD *)vs20_blit, &pc->vs); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->CreatePixelShader( +      pc->d3d9d, +      (const DWORD *)ps20_copy, &pc->ps_modes[pacc_mode_copy]); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->CreatePixelShader( +      pc->d3d9d, +      (const DWORD *)ps20_color, &pc->ps_modes[pacc_mode_color]); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->CreatePixelShader( +      pc->d3d9d, +      (const DWORD *)ps20_color_trans, &pc->ps_modes[pacc_mode_color_trans]); +  if (res != D3D_OK) goto err; + +  res = pc->d3d9d->lpVtbl->BeginStateBlock(pc->d3d9d); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetVertexDeclaration( +      pc->d3d9d, pc->vdecl); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetRenderState( +      pc->d3d9d, D3DRS_CULLMODE, D3DCULL_NONE); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetVertexShader( +      pc->d3d9d, pc->vs); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); +  if (res != D3D_OK) goto err; +#ifdef PACC_DEBUG_MSAA +  res = pc->d3d9d->lpVtbl->SetSamplerState( +      pc->d3d9d, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); +  if (res != D3D_OK) goto err; +#endif +  res = pc->d3d9d->lpVtbl->SetTexture( +      pc->d3d9d, 0, (IDirect3DBaseTexture9 *)pc->tex_pal); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->EndStateBlock(pc->d3d9d, &pc->state_common); +  if (res != D3D_OK) goto err; + +  res = pc->d3d9d->lpVtbl->BeginStateBlock(pc->d3d9d); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetPixelShader(pc->d3d9d, pc->ps_modes[pacc_mode_copy]); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->EndStateBlock(pc->d3d9d, &pc->state_modes[pacc_mode_copy]); +  if (res != D3D_OK) goto err; + +  res = pc->d3d9d->lpVtbl->BeginStateBlock(pc->d3d9d); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetPixelShader(pc->d3d9d, pc->ps_modes[pacc_mode_color]); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->EndStateBlock(pc->d3d9d, &pc->state_modes[pacc_mode_color]); +  if (res != D3D_OK) goto err; + +  res = pc->d3d9d->lpVtbl->BeginStateBlock(pc->d3d9d); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->SetPixelShader(pc->d3d9d, pc->ps_modes[pacc_mode_color_trans]); +  if (res != D3D_OK) goto err; +  res = pc->d3d9d->lpVtbl->EndStateBlock(pc->d3d9d, &pc->state_modes[pacc_mode_color_trans]); +  if (res != D3D_OK) goto err; + +  pc->renderthread = CreateThread(0, 0, pacc_renderproc, pc, 0, 0); +  if (!pc->renderthread) goto err; +  *vt = pacc_d3d9_vtable; +  *winvt = pacc_win_vtable; +  return pc; +err: +  pacc_delete(pc); +  return 0; +} diff --git a/pacc/pacc-gl-procs.inc b/pacc/pacc-gl-procs.inc new file mode 100644 index 0000000..cd991e0 --- /dev/null +++ b/pacc/pacc-gl-procs.inc @@ -0,0 +1,46 @@ +#ifndef PROC_NO_GL_1_3  +#ifndef PROC_NO_GL_1_1 +PROC(CLEAR, Clear) +PROC(DELETETEXTURES, DeleteTextures) +PROC(TEXIMAGE2D, TexImage2D) +PROC(CLEARCOLOR, ClearColor) +PROC(BINDTEXTURE, BindTexture) +PROC(GENTEXTURES, GenTextures) +PROC(TEXPARAMETERI, TexParameteri) +PROC(PIXELSTOREI, PixelStorei) +PROC(DRAWARRAYS, DrawArrays) +#endif // PROC_NO_GL_1_1 +PROC(ACTIVETEXTURE, ActiveTexture) +#endif // PROC_NO_GL_1_3 +PROC(DELETEPROGRAM, DeleteProgram) +PROC(CREATESHADER, CreateShader) +PROC(SHADERSOURCE, ShaderSource) +PROC(COMPILESHADER, CompileShader) +PROC(GETSHADERIV, GetShaderiv) +#ifndef NDEBUG +PROC(GETSHADERINFOLOG, GetShaderInfoLog) +#endif +PROC(DELETESHADER, DeleteShader) +PROC(CREATEPROGRAM, CreateProgram) +PROC(ATTACHSHADER, AttachShader) +PROC(BINDATTRIBLOCATION, BindAttribLocation) +PROC(LINKPROGRAM, LinkProgram) +PROC(GETPROGRAMIV, GetProgramiv) +#ifndef NDEBUG +PROC(GETPROGRAMINFOLOG, GetProgramInfoLog) +#endif +PROC(USEPROGRAM, UseProgram) +PROC(UNIFORM1I, Uniform1i) +PROC(GETUNIFORMLOCATION, GetUniformLocation) +PROC(DELETEBUFFERS, DeleteBuffers) +PROC(GENBUFFERS, GenBuffers) +PROC(UNIFORM1F, Uniform1f) +PROC(BINDBUFFER, BindBuffer) +PROC(BUFFERDATA, BufferData) +PROC(ENABLEVERTEXATTRIBARRAY, EnableVertexAttribArray) +PROC(VERTEXATTRIBPOINTER, VertexAttribPointer) +#ifdef PACC_GL_3 +PROC(DELETEVERTEXARRAYS, DeleteVertexArrays) +PROC(GENVERTEXARRAYS, GenVertexArrays) +PROC(BINDVERTEXARRAY, BindVertexArray) +#endif diff --git a/pacc/pacc-gl.c b/pacc/pacc-gl.c new file mode 100644 index 0000000..e6ed0a1 --- /dev/null +++ b/pacc/pacc-gl.c @@ -0,0 +1,505 @@ +#include "pacc-gl.h" +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include "pacc-gl-inc.h" + +#ifdef NDEBUG +#define DPRINTF(fmt, ...) +#else +#include <stdio.h> +#define DPRINTF(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) +#endif + +/* +  OpenGL versions: +  OpenGL 2.0 +  OpenGL 3.2 core (#define PACC_GL_3) +  OpenGL ES 2.0 (#define PACC_GL_ES) +  OpenGL ES 3.0 (#define PACC_GL_ES, #define PACC_GL_3) + +  Shader languages: +  GLSL 1.10 / GLSL ES 1.00 +*/ + +#ifdef PACC_GL_ES +#include "glsl/esheader.inc" +#else +#include "glsl/dsheader.inc" +#endif + +#include "glsl/blit.vert.inc" +#include "glsl/copy.frag.inc" +#include "glsl/color.frag.inc" +#include "glsl/color_trans.frag.inc" + +struct pacc_ctx { +  int w; +  int h; +  uint8_t pal[256*3]; +  bool pal_changed; +  uint8_t clearcolor[3]; +  GLuint tex_pal; +  GLuint progs[pacc_mode_count]; +  GLint uni_color, uni_color_trans; +  uint8_t color; +  bool color_changed; +  enum pacc_mode curr_mode; +}; + +struct pacc_buf { +  GLuint buf_obj; +  GLuint va_obj; // for OpenGL 3.2 Core +  GLfloat *buf; +  struct pacc_tex *tex; +  int len; +  int buflen; +  GLenum usage; +  bool changed; +}; + +struct pacc_tex { +  GLuint tex_obj; +  int w, h; +  bool changed; +  uint8_t *buf; +}; + +enum { +  VAI_COORD, +}; + +enum { +  PACC_BUF_DEF_LEN = 32, +  PRINTBUFLEN = 160, +}; + +static void pacc_delete(struct pacc_ctx *pc) { +  if (pc) { +    glDeleteTextures(1, &pc->tex_pal); +    for (int i = 0; i < pacc_mode_count; i++) { +      glDeleteProgram(pc->progs[i]); +    } +    free(pc); +  } +} + +static GLuint compile_shader(const uint8_t *ss, GLenum type) { +  GLuint s = glCreateShader(type); +  if (!s) goto err; +  const char *sourcelist[2] = { +#ifdef PACC_GL_ES +    (const char *)esheader, +#else +    (const char *)dsheader, +#endif +    (const char *)ss +  }; +  glShaderSource(s, 2, sourcelist, 0); +  glCompileShader(s); +  GLint res; +  glGetShaderiv(s, GL_COMPILE_STATUS, &res); +  if (!res) { +#ifndef NDEBUG +    glGetShaderiv(s, GL_INFO_LOG_LENGTH, &res); +    char *msgbuf = malloc(res); +    if (msgbuf) { +      glGetShaderInfoLog(s, res, 0, msgbuf); +      DPRINTF("%s shader error: \n%s\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment", msgbuf); +      DPRINTF("s:\n%s\n", ss); +      free(msgbuf); +    } +#endif +    goto err; +  } +  return s; +err: +  glDeleteShader(s); +  return 0; +} + +static GLuint compile_and_link(const uint8_t *vss, const uint8_t *fss) { +  GLuint p = 0, vs = 0, fs = 0; +  p = glCreateProgram(); +  if (!p) goto err; +  vs = compile_shader(vss, GL_VERTEX_SHADER); +  if (!vs) goto err; +  fs = compile_shader(fss, GL_FRAGMENT_SHADER); +  if (!fs) goto err; +  glAttachShader(p, vs); +  glAttachShader(p, fs); +  glBindAttribLocation(p, VAI_COORD, "coord"); +  glLinkProgram(p); +  GLint res; +  glGetProgramiv(p, GL_LINK_STATUS, &res); +  if (!res) { +#ifndef NDEBUG +    glGetProgramiv(p, GL_INFO_LOG_LENGTH, &res); +    char *msgbuf = malloc(res); +    if (msgbuf) { +      glGetProgramInfoLog(p, res, 0, msgbuf); +      DPRINTF("program link error: \n%s\n", msgbuf); +      DPRINTF("vs:\n%s\n", vss); +      DPRINTF("fs:\n%s\n", fss); +      free(msgbuf); +    } +#endif +    goto err; +  } +  glDeleteShader(vs); +  glDeleteShader(fs); +  glUseProgram(p); +  glUniform1i(glGetUniformLocation(p, "tex"), 1); +  return p; +err: +  glDeleteProgram(p); +  glDeleteShader(vs); +  glDeleteShader(fs); +  return 0; +} + +static void pacc_buf_delete(struct pacc_buf *pb) { +  if (pb) { +    free(pb->buf); +    glDeleteBuffers(1, &pb->buf_obj); +#ifdef PACC_GL_3 +    glDeleteVertexArrays(1, &pb->va_obj); +#endif +    free(pb); +  } +} + +static struct pacc_buf *pacc_gen_buf( +    struct pacc_ctx *pc, struct pacc_tex *pt, enum pacc_buf_mode mode) { +  struct pacc_buf *pb = malloc(sizeof(*pb)); +  if (!pb) goto err; +  *pb = (struct pacc_buf) { +    .buflen = PACC_BUF_DEF_LEN, +    .tex = pt, +    .usage = (mode == pacc_buf_mode_static) ? +      GL_STATIC_DRAW : GL_STREAM_DRAW, +  }; +  pb->buf = malloc(sizeof(*pb->buf) * pb->buflen); +  if (!pb->buf) goto err; +  glGenBuffers(1, &pb->buf_obj); +  if (!pb->buf_obj) goto err; +#ifdef PACC_GL_3 +  glGenVertexArrays(1, &pb->va_obj); +  if (!pb->va_obj) goto err; +  glBindVertexArray(pb->va_obj); +  glEnableVertexAttribArray(VAI_COORD); +  glBindBuffer(GL_ARRAY_BUFFER, pb->buf_obj); +  glVertexAttribPointer(VAI_COORD, 4, GL_FLOAT, GL_FALSE, 0, 0); +#endif +  return pb; +err: +  pacc_buf_delete(pb); +  return 0; +} + +static bool buf_reserve(struct pacc_buf *pb, int len) { +  if (pb->len + len > pb->buflen) { +    int newlen = pb->buflen; +    while (pb->len + len > newlen) newlen *= 2; +    GLfloat *newbuf = realloc(pb->buf, newlen * sizeof(pb->buf[0])); +    if (!newbuf) return false; +    pb->buflen = newlen; +    pb->buf = newbuf; +  } +  return true; +} + +static void pacc_calc_scale(float *ret, int w, int h, int wdest, int hdest) { +  ret[0] = ((float)w) / wdest; +  ret[1] = ((float)h) / hdest; +} + +static void pacc_calc_off_tex(float *ret, +                                     int tw, int th, int xsrc, int ysrc) { +  ret[0] = ((float)xsrc) / tw; +  ret[1] = ((float)ysrc) / th; +} + +static void pacc_calc_off( +    float *ret, int xdest, int ydest, int w, int h, int wdest, int hdest) { +  ret[0] = ((float)(xdest * 2 + w - wdest)) / wdest; +  ret[1] = ((float)(ydest * 2 + h - hdest)) / hdest; +} + +static void pacc_buf_rect_off( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, int w, int h, int xoff, int yoff) { +  float scale[2]; +  float off[2]; +  float tscale[2]; +  float toff[2]; +  pacc_calc_off(off, x, y, w, h, pc->w, pc->h); +  pacc_calc_scale(scale, w, h, pc->w, pc->h); +  pacc_calc_off_tex(toff, pb->tex->w, pb->tex->h, xoff, yoff); +  pacc_calc_scale(tscale, w, h, pb->tex->w, pb->tex->h); +  GLfloat coord[16] = { +    -1.0f * scale[0] + off[0], -1.0f * scale[1] - off[1], +     0.0f * tscale[0] + toff[0],  1.0f * tscale[1] + toff[1], + +    -1.0f * scale[0] + off[0],  1.0f * scale[1] - off[1], +     0.0f * tscale[0] + toff[0],  0.0f * tscale[1] + toff[1], + +     1.0f * scale[0] + off[0], -1.0f * scale[1] - off[1], +     1.0f * tscale[0] + toff[0],  1.0f * tscale[1] + toff[1], + +     1.0f * scale[0] + off[0],  1.0f * scale[1] - off[1], +     1.0f * tscale[0] + toff[0],  0.0f * tscale[1] + toff[1], +  }; +  if (!buf_reserve(pb, 24)) return; +  int indices[6] = {0, 1, 2, 2, 1, 3}; +  for (int i = 0; i < 6; i++) { +    for (int j = 0; j < 4; j++) { +      pb->buf[pb->len+i*4+j] = coord[indices[i]*4+j]; +    } +  } +  pb->len += 24; +  pb->changed = true; +} + +static void pacc_buf_vprintf( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, const char *fmt, va_list ap) { +  uint8_t printbuf[PRINTBUFLEN+1]; +  vsnprintf((char *)printbuf, sizeof(printbuf), fmt, ap); +  int len = strlen((const char *)printbuf); +  float scale[2]; +  float off[2]; +  int w = pb->tex->w / 256; +  int h = pb->tex->h; +  pacc_calc_scale(scale, w, h, pc->w, pc->h); +  pacc_calc_off(off, x, y, w, h, pc->w, pc->h); +  if (!buf_reserve(pb, len*24)) return; +  GLfloat *coords = pb->buf + pb->len; +  for (int i = 0; i < len; i++) { +    coords[24*i+0*4+0]                      = (-1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+0*4+1]                      = -1.0f * scale[1] - off[1]; +    coords[24*i+1*4+0] = coords[24*i+4*4+0] = (-1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+1*4+1] = coords[24*i+4*4+1] = 1.0f * scale[1] - off[1]; +    coords[24*i+2*4+0] = coords[24*i+3*4+0] = (1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+2*4+1] = coords[24*i+3*4+1] = -1.0f * scale[1] - off[1]; +    coords[24*i+5*4+0]                      = (1.0f + 2.0f*i) * scale[0] + off[0]; +    coords[24*i+5*4+1]                      = 1.0f * scale[1] - off[1]; +    coords[24*i+0*4+2]                      = ((float)printbuf[i]) / 256.0f; +    coords[24*i+0*4+3]                      = 1.0f; +    coords[24*i+1*4+2] = coords[24*i+4*4+2] = ((float)printbuf[i]) / 256.0f; +    coords[24*i+1*4+3] = coords[24*i+4*4+3] = 0.0f; +    coords[24*i+2*4+2] = coords[24*i+3*4+2] = ((float)(printbuf[i]+1)) / 256.0f; +    coords[24*i+2*4+3] = coords[24*i+3*4+3] = 1.0f; +    coords[24*i+5*4+2]                      = ((float)(printbuf[i]+1)) / 256.0f; +    coords[24*i+5*4+3]                      = 0.0f; +  } +  pb->len += len * 24; +  pb->changed = true; +} + +static void pacc_buf_printf( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, const char *fmt, ...) { +  va_list ap; +  va_start(ap, fmt); +  pacc_buf_vprintf(pc, pb, x, y, fmt, ap); +  va_end(ap); +} + +static void pacc_buf_rect( +    const struct pacc_ctx *pc, struct pacc_buf *pb, +    int x, int y, int w, int h) { +  pacc_buf_rect_off(pc, pb, x, y, w, h, 0, 0); +} + +static void pacc_buf_clear(struct pacc_buf *pb) { +  pb->len = 0; +  pb->changed = true; +} + +static void pacc_palette(struct pacc_ctx *pc, const uint8_t *rgb, int colors) { +  memcpy(pc->pal, rgb, colors*3); +  pc->pal_changed = true; +} + +static void pacc_color(struct pacc_ctx *pc, uint8_t pal) { +  pc->color = pal; +  pc->color_changed = true; +} + +static void pacc_begin_clear(struct pacc_ctx *pc) { +  if (pc->pal_changed) { +    glActiveTexture(GL_TEXTURE0); +    glTexImage2D( +        GL_TEXTURE_2D, +        0, GL_RGB, +        256, 1, +        0, GL_RGB, +        GL_UNSIGNED_BYTE, pc->pal); +    pc->pal_changed = false; +    glActiveTexture(GL_TEXTURE1); +  } +  if (memcmp(pc->clearcolor, pc->pal, 3)) { +    memcpy(pc->clearcolor, pc->pal, 3); +    glClearColor( +        pc->clearcolor[0] / 255.f, +        pc->clearcolor[1] / 255.f, +        pc->clearcolor[2] / 255.f, +        1.0f); +  } +  glClear(GL_COLOR_BUFFER_BIT); +  pc->curr_mode = pacc_mode_count; +} + +static void pacc_draw(struct pacc_ctx *pc, struct pacc_buf *pb, enum pacc_mode mode) { +  if (!pb->len) return; +  if (mode >= pacc_mode_count) return; +  if (pc->curr_mode != mode) { +    glUseProgram(pc->progs[mode]); +    pc->curr_mode = mode; +  } +  if (mode != pacc_mode_copy && pc->color_changed) { +    glUniform1f(pc->uni_color, pc->color / 255.f); +    glUniform1f(pc->uni_color_trans, pc->color / 255.f); +    pc->color_changed = false; +  } +  glBindTexture(GL_TEXTURE_2D, pb->tex->tex_obj); +  if (pb->tex->changed) { +    GLint format; +#if PACC_GL_3 +    format = GL_RED; +#else +    format = GL_LUMINANCE; +#endif +    glTexImage2D( +        GL_TEXTURE_2D, +        0, format, +        pb->tex->w, pb->tex->h, +        0, format, GL_UNSIGNED_BYTE, +        pb->tex->buf); +    pb->tex->changed = false; +  } +  if (pb->changed) { +    glBindBuffer(GL_ARRAY_BUFFER, pb->buf_obj); +    glBufferData( +        GL_ARRAY_BUFFER, +        pb->len * sizeof(pb->buf[0]), pb->buf, +        pb->usage); +    pb->changed = false; +  } +#ifdef PACC_GL_3 +  glBindVertexArray(pb->va_obj); +#else +  glEnableVertexAttribArray(VAI_COORD); +  glBindBuffer(GL_ARRAY_BUFFER, pb->buf_obj); +  glVertexAttribPointer(VAI_COORD, 4, GL_FLOAT, GL_FALSE, 0, 0); +#endif +  glDrawArrays(GL_TRIANGLES, 0, pb->len / 4); +} + +static uint8_t *pacc_tex_lock(struct pacc_tex *pt) { +  return pt->buf; +} + +static void pacc_tex_unlock(struct pacc_tex *pt) { +  pt->changed = true; +} + +static void pacc_tex_delete(struct pacc_tex *pt) { +  if (pt) { +    glDeleteTextures(1, &pt->tex_obj); +    free(pt->buf); +    free(pt); +  } +} + +static struct pacc_tex *pacc_gen_tex(struct pacc_ctx *pc, int w, int h) { +  struct pacc_tex *pt = malloc(sizeof(*pt)); +  if (!pt) goto err; +  *pt = (struct pacc_tex) { +    .w = w, +    .h = h, +    .buf = calloc(w*h, 1), +  }; +  if (!pt->buf) goto err; +  glGenTextures(1, &pt->tex_obj); +  glBindTexture(GL_TEXTURE_2D, pt->tex_obj); +  GLint format; +#ifdef PACC_GL_3 +  format = GL_RED; +#else +  format = GL_LUMINANCE; +#endif +  glTexImage2D( +      GL_TEXTURE_2D, +      0, format, +      w, h, 0, +      format, GL_UNSIGNED_BYTE, +      pt->buf); +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +  if (w & (w - 1)) { +    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +  } +  if (h & (h - 1)) { +    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +  } +  return pt; +err: +  pacc_tex_delete(pt); +  return 0; +} + +static struct pacc_vtable pacc_gl_vtable = { +  .pacc_delete = pacc_delete, +  .gen_buf = pacc_gen_buf, +  .gen_tex = pacc_gen_tex, +  .buf_delete = pacc_buf_delete, +  .tex_lock = pacc_tex_lock, +  .tex_unlock = pacc_tex_unlock, +  .tex_delete = pacc_tex_delete, +  .buf_rect = pacc_buf_rect, +  .buf_rect_off = pacc_buf_rect_off, +  .buf_vprintf = pacc_buf_vprintf, +  .buf_printf = pacc_buf_printf, +  .buf_clear = pacc_buf_clear, +  .palette = pacc_palette, +  .color = pacc_color, +  .begin_clear = pacc_begin_clear, +  .draw = pacc_draw, +}; + +struct pacc_ctx *pacc_init_gl(int w, int h, struct pacc_vtable *vt) { +  struct pacc_ctx *pc = malloc(sizeof(*pc)); +  if (!pc) goto err; +  *pc = (struct pacc_ctx) { +    .w = w, +    .h = h, +  }; +  glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +  glGenTextures(1, &pc->tex_pal); +  glBindTexture(GL_TEXTURE_2D, pc->tex_pal); +  glTexImage2D( +      GL_TEXTURE_2D, +      0, GL_RGB, +      256, 1, 0, +      GL_RGB, GL_UNSIGNED_BYTE, +      pc->pal); +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +  pc->progs[pacc_mode_copy] = compile_and_link(blit_vert, copy_frag); +  if (!pc->progs[pacc_mode_copy]) goto err; +  pc->progs[pacc_mode_color] = compile_and_link(blit_vert, color_frag); +  if (!pc->progs[pacc_mode_color]) goto err; +  pc->progs[pacc_mode_color_trans] = compile_and_link(blit_vert, color_trans_frag); +  if (!pc->progs[pacc_mode_color_trans]) goto err; +  pc->uni_color = glGetUniformLocation(pc->progs[pacc_mode_color], "color"); +  pc->uni_color_trans = glGetUniformLocation(pc->progs[pacc_mode_color_trans], "color"); +  glActiveTexture(GL_TEXTURE1); +  *vt = pacc_gl_vtable; +  return pc; +err: +  pacc_delete(pc); +  return 0; +} + diff --git a/pacc/pacc-gl.h b/pacc/pacc-gl.h new file mode 100644 index 0000000..2f5ccff --- /dev/null +++ b/pacc/pacc-gl.h @@ -0,0 +1,8 @@ +#ifndef MYON_PACC_GL_H_INCLUDED +#define MYON_PACC_GL_H_INCLUDED + +#include "pacc.h" + +struct pacc_ctx *pacc_init_gl(int w, int h, struct pacc_vtable *vt); + +#endif // MYON_PACC_GL_H_INCLUDED diff --git a/pacc/pacc-win.h b/pacc/pacc-win.h new file mode 100644 index 0000000..47c09d1 --- /dev/null +++ b/pacc/pacc-win.h @@ -0,0 +1,21 @@ +#ifndef MYON_PACC_WIN_H_INCLUDED +#define MYON_PACC_WIN_H_INCLUDED + +#include "pacc.h" + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <stdbool.h> + +typedef void pacc_rendercb(void *ptr); + +struct pacc_win_vtable { +  void (*renderctrl)(struct pacc_ctx *ctx, bool enable); +}; + +struct pacc_ctx *pacc_init_d3d9(HWND hwnd, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt); + +#endif // MYON_PACC_WIN_H_INCLUDED + diff --git a/pacc/pacc.h b/pacc/pacc.h new file mode 100644 index 0000000..b3387ac --- /dev/null +++ b/pacc/pacc.h @@ -0,0 +1,53 @@ +#ifndef MYON_PACC_H_INCLUDED +#define MYON_PACC_H_INCLUDED + +#include <stdint.h> +#include <stdarg.h> + +enum pacc_mode { +  pacc_mode_copy, +  pacc_mode_color, +  pacc_mode_color_trans, +  pacc_mode_count, +}; + +enum pacc_buf_mode { +  pacc_buf_mode_static, +  pacc_buf_mode_stream, +}; + +struct pacc_ctx; +struct pacc_tex; +struct pacc_buf; + +struct pacc_vtable { +  void (*pacc_delete)(struct pacc_ctx *pc); +  struct pacc_buf *(*gen_buf)( +      struct pacc_ctx *pc, struct pacc_tex *pt, enum pacc_buf_mode mode); +  struct pacc_tex *(*gen_tex)(struct pacc_ctx *pc, int w, int h); +  void (*buf_delete)(struct pacc_buf *buf); +  uint8_t *(*tex_lock)(struct pacc_tex *tex); +  void (*tex_unlock)(struct pacc_tex *tex); +  void (*tex_delete)(struct pacc_tex *tex); +  void (*buf_rect)( +      const struct pacc_ctx *ctx, struct pacc_buf *buf, +      int x, int y, int w, int h); +  void (*buf_rect_off)( +      const struct pacc_ctx *ctx, struct pacc_buf *buf, +      int x, int y, int w, int h, int xoff, int yoff); +  void (*buf_vprintf)( +      const struct pacc_ctx *ctx, struct pacc_buf *buf, +      int x, int y, const char *fmt, va_list ap); +  void (*buf_printf)( +      const struct pacc_ctx *ctx, struct pacc_buf *buf, +      int x, int y, const char *fmt, ...); +  void (*buf_clear)(struct pacc_buf *buf); +  void (*palette)(struct pacc_ctx *ctx, const uint8_t *rgb, int colors); +  void (*color)(struct pacc_ctx *ctx, uint8_t pal); +  void (*begin_clear)(struct pacc_ctx *ctx); +  void (*draw)(struct pacc_ctx *ctx, struct pacc_buf *buf, enum pacc_mode mode); +}; + +struct pacc_ctx *pacc_init_gl(int w, int h, struct pacc_vtable *vt); + +#endif // MYON_PACC_H_INCLUDED | 
