1 #include <bz/renderer/renderer_internal.h>
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>
10 struct BZRendererPass {
15 const static size_t kMaxRenderPasses = 8;
18 BZRendererConfiguration configuration;
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];
29 BZRendererID bzRendererInit(BZMemoryArenaID arena, const BZRendererConfiguration *configuration, const char *title) {
30 BZRendererID renderer = (BZRenderer *)bzMemoryAlloc(arena, sizeof(BZRenderer));
32 renderer->configuration = *configuration;
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());
40 renderer->renderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED/*SDL_RENDERER_ACCELERATED*/);
42 //SDL_Surface *windowSurface = SDL_GetWindowSurface(window);
43 SDL_GetWindowSizeInPixels(renderer->window, &renderer->outputWidth, &renderer->outputHeight);
45 renderer->renderTexture = SDL_CreateTexture(renderer->renderer, SDL_PIXELFORMAT_ABGR8888/*SDL_PIXELFORMAT_RBZA8888*/, SDL_TEXTUREACCESS_STREAMING, configuration->rendererWidth, configuration->rendererHeight);
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);
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);
55 for (size_t i = 0; i < kMaxRenderPasses; ++i) {
56 renderer->rendererPasses[i].pass = NULL;
59 SDL_ShowCursor(SDL_DISABLE);
61 bzGfxPreparePalettes(arena, 8, configuration->palette->numColors);
62 bzGfxPrepareCanvasBuffer(arena, configuration->gameWidth, configuration->gameHeight);
67 void bzRendererTeardown(BZRendererID renderer) {
68 SDL_DestroyWindow(renderer->window);
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];
81 void bzRendererUnregisterPass(BZRendererPassID rendererPass) {
82 rendererPass->pass = NULL;
85 void bzRendererBlit(BZRendererID renderer) {
86 //SDL_LockSurface(drawSurface);
88 //SDL_Rect srcRect = { .x = 0, .y = 0, .w = drawSurface->w, .h = drawSurface->h };
92 SDL_LockTexture(renderer->renderTexture, NULL, &pixels, &pitch);
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);
103 //SDL_UnlockSurface(drawSurface);
105 SDL_UnlockTexture(renderer->renderTexture);
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);
113 //SDL_SetRenderTarget(renderer, NULL);
114 //SDL_RenderClear(renderer);
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);
122 //SDL_RenderCopyEx(renderer, renderTextureIntermediate, NULL, NULL, 0, NULL, 0);
125 // SDL_RenderPresent(renderer);
126 //SDL_RenderPresent(renderer);
127 //SDL_SetRenderTarget(renderer, renderTexture);
129 //SDL_UpdateWindowSurface(window);
130 //SDL_UpdateWindowSurface(window);
131 //SDL_UpdateWindowSurface(window);
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);