]> git.bts.cx Git - benzene.git/blob - src_platform/sdl/bz/renderer/renderer.c
Initial version
[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 }