]> git.bts.cx Git - benzene.git/blob - src_platform/sdl/bz/renderer/renderer.c
Sprites
[benzene.git] / src_platform / sdl / bz / renderer / renderer.c
1 #include <bz/renderer/renderer_internal.h>
2
3 #include <bz/gfx/gfx_internal.h>
4 #include <bz/math/math.h>
5 #include <bz/memory/allocator.h>
6 #include <bz/renderer/palette_internal.h>
7 #include <bz/renderer/render_pass_internal.h>
8 #include <SDL.h>
9
10 struct BZRendererPass {
11 size_t idx;
12 BZRenderPassID pass;
13 };
14
15 const static size_t kMaxRenderPasses = 8;
16
17 struct BZRenderer {
18 BZRendererConfiguration configuration;
19 SDL_Window *window;
20 SDL_Renderer *renderer;
21 SDL_Texture *renderTexture;
22 SDL_Texture *renderTextureIntermediate;
23 size_t intermediateWidth, intermediateHeight;
24 int outputWidth, outputHeight;
25 //static size_t numRenderPasses = 0;
26 BZRendererPass rendererPasses[kMaxRenderPasses];
27 };
28
29 BZRendererID bzRendererInit(BZMemoryArenaID arena, const BZRendererConfiguration *configuration, const char *title) {
30 BZRendererID renderer = (BZRenderer *)bzMemoryAlloc(arena, sizeof(BZRenderer));
31
32 renderer->configuration = *configuration;
33
34 renderer->window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, configuration->outputWidth, configuration->outputHeight, SDL_WINDOW_ALLOW_HIGHDPI);
35 if (renderer->window == NULL) {
36 bzError("Could not make window: SDL_Error='%s'", SDL_GetError());
37 return NULL;
38 }
39
40 renderer->renderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED/*SDL_RENDERER_ACCELERATED*/);
41
42 //SDL_Surface *windowSurface = SDL_GetWindowSurface(window);
43 SDL_GetWindowSizeInPixels(renderer->window, &renderer->outputWidth, &renderer->outputHeight);
44
45 renderer->renderTexture = SDL_CreateTexture(renderer->renderer, SDL_PIXELFORMAT_ABGR8888/*SDL_PIXELFORMAT_RBZA8888*/, SDL_TEXTUREACCESS_STREAMING, configuration->rendererWidth, configuration->rendererHeight);
46
47 renderer->intermediateWidth = configuration->rendererWidth * bzFloor((renderer->outputWidth / configuration->rendererWidth) + 1);
48 renderer->intermediateHeight = configuration->rendererHeight * bzFloor((renderer->outputHeight / configuration->rendererHeight) + 1);
49 renderer->renderTextureIntermediate = SDL_CreateTexture(renderer->renderer, SDL_PIXELFORMAT_ABGR8888/*SDL_PIXELFORMAT_RBZA8888*/, SDL_TEXTUREACCESS_TARGET, renderer->intermediateWidth, renderer->intermediateHeight);
50 SDL_SetTextureScaleMode(renderer->renderTextureIntermediate, SDL_ScaleModeBest);
51
52 // drawSurface/*tmpSurface*/ = SDL_CreateRBZSurface(0, RENDERER_WIDTH, RENDERER_HEIGHT, windowSurface->format->BytesPerPixel * 8, windowSurface->format->Rmask, windowSurface->format->Gmask, windowSurface->format->Bmask, windowSurface->format->Amask);
53 //drawSurface = SDL_CreateRBZSurface(0, RENDERER_WIDTH, RENDERER_HEIGHT, 8, 0, 0, 0, 0);
54
55 for (size_t i = 0; i < kMaxRenderPasses; ++i) {
56 renderer->rendererPasses[i].pass = NULL;
57 }
58
59 SDL_ShowCursor(SDL_DISABLE);
60
61 bzGfxPreparePalettes(arena, 8, configuration->palette->numColors);
62 bzGfxPrepareCanvasBuffer(arena, configuration->gameWidth, configuration->gameHeight);
63
64 return renderer;
65 }
66
67 void bzRendererTeardown(BZRendererID renderer) {
68 SDL_DestroyWindow(renderer->window);
69 }
70
71 BZRendererPassID bzRendererRegisterPass(BZRendererID renderer, BZRenderPassID renderPass) {
72 for (size_t i = 0; i < kMaxRenderPasses; ++i) {
73 if (renderer->rendererPasses[i].pass == NULL) {
74 renderer->rendererPasses[i].pass = renderPass;
75 return &renderer->rendererPasses[i];
76 }
77 }
78 return NULL;
79 }
80
81 void bzRendererUnregisterPass(BZRendererPassID rendererPass) {
82 rendererPass->pass = NULL;
83 }
84
85 void bzRendererBlit(BZRendererID renderer) {
86 //SDL_LockSurface(drawSurface);
87
88 //SDL_Rect srcRect = { .x = 0, .y = 0, .w = drawSurface->w, .h = drawSurface->h };
89 void *pixels;
90 int pitch;
91
92 SDL_LockTexture(renderer->renderTexture, NULL, &pixels, &pitch);
93
94 for (size_t i = 0; i < kMaxRenderPasses; ++i) {
95 BZRenderPass *renderPass = renderer->rendererPasses[i].pass;
96 if (renderPass != NULL) {
97 if (renderPass->softwareHook != NULL) {
98 renderPass->softwareHook(renderer->configuration.palette, (uint32_t *)pixels/*drawSurface->pixels*/, renderer->configuration.gameWidth, renderer->configuration.gameHeight, renderer->configuration.rendererWidth / renderer->configuration.gameWidth, renderer->configuration.rendererHeight / renderer->configuration.gameHeight);
99 }
100 }
101 }
102
103 //SDL_UnlockSurface(drawSurface);
104
105 SDL_UnlockTexture(renderer->renderTexture);
106
107 //SDL_Rect srcRect = { .x = 0, .y = 0, .w = drawSurface->w, .h = drawSurface->h };
108 //SDL_Rect dstRect = { .x = 0, .y = 0, .w = windowSurface->w, .h = windowSurface->h};
109 //SDL_FillRect(windowSurface, &dstRect, 100);
110 // int zis = SDL_BlitSurface(drawSurface, &srcRect, tmpSurface, &srcRect);
111 // int zi = SDL_BlitScaled(drawSurface, &srcRect, windowSurface, &dstRect);
112
113 //SDL_SetRenderTarget(renderer, NULL);
114 //SDL_RenderClear(renderer);
115
116 SDL_SetRenderTarget(renderer->renderer, renderer->renderTextureIntermediate);
117 //renderTextureIntermediate
118 SDL_RenderCopyEx(renderer->renderer, renderer->renderTexture, NULL, NULL, 0, NULL, 0);
119 SDL_SetRenderTarget(renderer->renderer, NULL);
120
121
122 //SDL_RenderCopyEx(renderer, renderTextureIntermediate, NULL, NULL, 0, NULL, 0);
123
124
125 // SDL_RenderPresent(renderer);
126 //SDL_RenderPresent(renderer);
127 //SDL_SetRenderTarget(renderer, renderTexture);
128
129 //SDL_UpdateWindowSurface(window);
130 //SDL_UpdateWindowSurface(window);
131 //SDL_UpdateWindowSurface(window);
132 }
133
134 void bzRendererVBlank(BZRendererID renderer) {
135 SDL_RenderClear(renderer->renderer);
136 size_t height = (size_t)((float)renderer->outputWidth * (float)renderer->configuration.rendererHeight / (float)renderer->configuration.rendererWidth);
137 SDL_Rect dstRect = { .x = 0, .y = (renderer->outputHeight - height) / 2, .w = renderer->outputWidth, .h = height };
138 SDL_RenderCopyEx(renderer->renderer, renderer->renderTextureIntermediate, NULL, &dstRect, 0, NULL, 0);
139 SDL_RenderPresent(renderer->renderer);
140 }