Implement SACT2.GetMainSurfaceNumber

Sprites are now rendered to an off-screen texture which is then rendered
to the screen in gfx_swap. The sprite table in sact_graphics is set up
so that sprites[-1] provides access to this off-screen texture.
This commit is contained in:
Nunuhara Cabbage
2019-12-20 20:18:17 -08:00
parent 5acf0a6e4c
commit 6bef461a5d
4 changed files with 91 additions and 9 deletions
+1
View File
@@ -66,6 +66,7 @@ struct gfx_render_job {
int gfx_init(void);
void gfx_fini(void);
Texture *gfx_main_surface(void);
void gfx_set_window_size(int w, int h);
void gfx_fullscreen(bool on);
void gfx_set_wait_vsync(bool wait);
+1 -1
View File
@@ -42,7 +42,7 @@ hll_defun_inline(GetScreenWidth, config.view_width);
// int GetScreenHeight(void)
hll_defun_inline(GetScreenHeight, config.view_height);
// int GetMainSurfaceNumber(void)
hll_unimplemented(SACT2, GetMainSurfaceNumber);
hll_defun_inline(GetMainSurfaceNumber, -1);
// int Update(void)
hll_defun_inline(Update, sact_Update());
// int Effect(int nType, int nTime, int nfKey)
+26 -5
View File
@@ -23,6 +23,8 @@
#include "vm_string.h"
#include "utfsjis.h"
static struct sact_sprite *create_sprite(int sp_no, int width, int height, int r, int g, int b, int a);
static struct sact_sprite **sprites = NULL;
static int nr_sprites = 0;
@@ -31,7 +33,7 @@ TAILQ_HEAD(listhead, sact_sprite) sprite_list =
struct sact_sprite *sact_get_sprite(int sp)
{
if (sp < 0 || sp >= nr_sprites)
if (sp < -1 || sp >= nr_sprites)
return NULL;
return sprites[sp];
}
@@ -81,10 +83,32 @@ static void sprite_unregister(struct sact_sprite *sp)
TAILQ_REMOVE(&sprite_list, sp, entry);
}
static void realloc_sprite_table(int n)
{
int old_nr_sprites = nr_sprites;
nr_sprites = n;
struct sact_sprite **tmp = xrealloc(sprites-1, sizeof(struct sact_sprite*) * (nr_sprites+1));
sprites = tmp + 1;
memset(sprites + old_nr_sprites, 0, sizeof(struct sact_sprite*) * (nr_sprites - old_nr_sprites));
}
int sact_Init(void)
{
gfx_init();
gfx_font_init();
nr_sprites = 256;
sprites = xmalloc(sizeof(struct sact_sprite*) * 257);
memset(sprites, 0, sizeof(struct sact_sprite*) * 257);
// create sprite for main_surface
Texture *t = gfx_main_surface();
struct sact_sprite *sp = create_sprite(0, t->w, t->h, 0, 0, 0, 255);
sp->texture = *t; // XXX: textures normally shouldn't be copied like this...
sprites++;
return 1;
}
@@ -237,11 +261,8 @@ int sact_SP_GetUnuseNum(int min)
return i;
}
int old_nr_sprites = nr_sprites;
int n = max(min, nr_sprites);
nr_sprites = n + 256;
sprites = xrealloc(sprites, sizeof(struct sact_sprite*) * nr_sprites);
memset(sprites + old_nr_sprites, 0, sizeof(struct sact_sprite*) * (nr_sprites - old_nr_sprites));
realloc_sprite_table(n + 256);
return n;
}
+63 -3
View File
@@ -42,7 +42,7 @@
static GLfloat world_view_transform[16] = {
[10] = 2,
[12] = -1,
[13] = 1,
[13] = -1,
[14] = -1,
[15] = 1
};
@@ -52,6 +52,9 @@ struct default_shader {
GLuint alpha_mod;
} default_shader;
GLuint main_surface_fb;
struct texture main_surface;
void prepare_default_shader(struct gfx_render_job *job, void *data)
{
struct default_shader *s = (struct default_shader*)job->shader;
@@ -133,6 +136,7 @@ static int gl_initialize(void)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
return 0;
}
@@ -179,6 +183,11 @@ void gfx_fini(void)
SDL_Quit();
}
Texture *gfx_main_surface(void)
{
return &main_surface;
}
void gfx_fullscreen(bool on)
{
if (on && !sdl.fs_on) {
@@ -190,13 +199,37 @@ void gfx_fullscreen(bool on)
}
}
static void main_surface_init(int w, int h)
{
gfx_delete_texture(&main_surface);
glGenTextures(1, &main_surface.handle);
glBindTexture(GL_TEXTURE_2D, main_surface.handle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
main_surface.w = w;
main_surface.h = h;
main_surface.has_alpha = true;
main_surface.alpha_mod = 255;
main_surface.draw_method = DRAW_METHOD_NORMAL;
glGenFramebuffers(1, &main_surface_fb);
glBindFramebuffer(GL_FRAMEBUFFER, main_surface_fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, main_surface.handle, 0);
}
void gfx_set_window_size(int w, int h)
{
sdl.w = w;
sdl.h = h;
world_view_transform[0] = 2.0 / w;
world_view_transform[5] = -2.0 / h;
world_view_transform[5] = 2.0 / h;
SDL_SetWindowSize(sdl.window, w, h);
main_surface_init(w, h);
}
void gfx_set_wait_vsync(bool wait)
@@ -211,7 +244,34 @@ void gfx_clear(void)
void gfx_swap(void)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
static GLfloat mw_transform[16] = {
[0] = 1,
[5] = 1,
[10] = 1,
[15] = 1
};
static GLfloat wv_transform[16] = {
[0] = 2,
[5] = -2,
[10] = 1,
[12] = -1,
[13] = 1,
[15] = 1
};
struct gfx_render_job job = {
.shader = &default_shader.s,
.texture = main_surface.handle,
.world_transform = mw_transform,
.view_transform = wv_transform,
.data = &main_surface
};
gfx_render(&job);
SDL_GL_SwapWindow(sdl.window);
glBindFramebuffer(GL_FRAMEBUFFER, main_surface_fb);
}
/*
@@ -371,7 +431,7 @@ GLuint gfx_set_framebuffer(GLenum target, Texture *t, int x, int y, int w, int h
void gfx_reset_framebuffer(GLenum target, GLuint fbo)
{
glBindFramebuffer(target, 0);
glBindFramebuffer(target, main_surface_fb);
glDeleteFramebuffers(1, &fbo);
glViewport(0, 0, sdl.w, sdl.h);
}