<commit_before>/* ============================================================================
 *  Controller.c: Video rendering.
 *
 *  VIDEOSIM: VIDEO Interface SIMulator.
 *  Copyright (C) 2013, <NAME>.
 *  All rights reserved.
 *
 *  This file is subject to the terms and conditions defined in
 *  file 'LICENSE', which is part of this source code package.
 * ========================================================================= */
#include "Controller.h"
#include "Externs.h"
#include "Render.h"

#ifdef __cplusplus
#include <cassert>
#include <cstring>
#else
#include <assert.h>
#include <string.h>
#endif

#include <GL/glfw.h>

static void RenderFrame16(struct VIFController *controller);

/* ============================================================================
 *  RenderFrame: Draws a frame to the display.
 * ========================================================================= */
void
RenderFrame(struct VIFController *controller) {
  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  debug("== Rastering Frame ==");
  debugarg("Height:  [%u].", controller->renderArea.height);
  debugarg("Width:   [%u].", controller->renderArea.width);
  debugarg("X Start: [%u].", controller->renderArea.x.start);
  debugarg("X End:   [%u].", controller->renderArea.x.end);
  debugarg("Y Start: [%u].", controller->renderArea.y.start);
  debugarg("Y End:   [%u].", controller->renderArea.y.end);

  switch(controller->regs[VI_STATUS_REG] & 0x3) {
  case 0:
    break;

  case 1:
    assert(0 && "Attempted to use reversed frame type.");
    break;

  case 2:
    RenderFrame16(controller);
    break;

  case 3:
    assert(0 && "32-bit frame.");
    break;
  }

  glfwPollEvents();
  glfwSwapBuffers();
}

/* ============================================================================
 *  Renders a 16-bit frame.
 * ========================================================================= */
static void
RenderFrame16(struct VIFController *controller) {
  uint32_t offset = controller->regs[VI_ORIGIN_REG] & 0xFFFFFF;
  const uint8_t *buffer = BusGetRDRAMPointer(controller->bus) + offset;

  int hdiff = controller->renderArea.x.end - controller->renderArea.x.start;
  int vdiff = controller->renderArea.y.end - controller->renderArea.y.start;
  float hcoeff = (float)(controller->regs[VI_X_SCALE_REG] & 0xFFF) / (1 << 10);
  float vcoeff = (float)(controller->regs[VI_Y_SCALE_REG] & 0xFFF) / (1 << 10);
  unsigned hres = (hdiff * hcoeff);
  unsigned vres = (vdiff * vcoeff);

  int hskip = controller->regs[VI_WIDTH_REG] - hres;

  debugarg("H Res:   [%u].", hres);
  debugarg("V Res:   [%u].", vres);
  debugarg("H Skip:  [%d].", hskip);

  if (vdiff <= 0 || hdiff <= 0 || !offset)
    return;

  /* Hacky? */
  if (hres > 640) {
    hskip += (hres - 640);
    hres = 640;
  }

  if (vres > 480) {
    vres = 480;
  }

  glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA,
    controller->renderArea.width,
    controller->renderArea.height,
    0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, buffer);

  glBegin(GL_QUADS);
    glTexCoord2i(0, 0);
    glVertex2i(0, 0);
    glTexCoord2i(controller->renderArea.width, 0);
    glVertex2i(controller->renderArea.width, 0);
    glTexCoord2i(controller->renderArea.width, controller->renderArea.height);
    glVertex2i(controller->renderArea.width, controller->renderArea.height);
    glTexCoord2i(0, controller->renderArea.height);
    glVertex2i(0, controller->renderArea.height);
  glEnd();
}

/* ============================================================================
 *  ResetPerspective: Calculates the coordinates of the visible area.
 * ========================================================================= */
void
ResetPerspective(struct VIFController *controller) {
  struct RenderArea *renderArea = &controller->renderArea;

  /* Calculate the bounding positions. */
  renderArea->x.start = controller->regs[VI_H_START_REG] >> 16 & 0x3FF;
  renderArea->x.end = controller->regs[VI_H_START_REG] & 0x3FF;
  renderArea->y.start = controller->regs[VI_V_START_REG] >> 16 & 0x3FF;
  renderArea->y.end = controller->regs[VI_V_START_REG] & 0x3FF;

  renderArea->y.end /= 2;
  renderArea->y.start /= 2;

  /* Calculate the height and width. */
  renderArea->height = ((controller->regs[VI_Y_SCALE_REG] & 0xFFF) *
    (renderArea->y.end - renderArea->y.start)) / 0x400;

  renderArea->width = ((controller->regs[VI_X_SCALE_REG] & 0xFFF) *
    (renderArea->x.end - renderArea->x.start)) / 0x400;

  /* Catch impossible conditions. */
  renderArea->width = (renderArea->width > 640) ? 640 : renderArea->width;
  renderArea->height = (renderArea->height > 480) ? 480 : renderArea->height;

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, renderArea->width, renderArea->height, 0, 0, 1);
}

<commit_msg>Fix rendering of some ROMs.<commit_after>/* ============================================================================
 *  Controller.c: Video rendering.
 *
 *  VIDEOSIM: VIDEO Interface SIMulator.
 *  Copyright (C) 2013, <NAME>.
 *  All rights reserved.
 *
 *  This file is subject to the terms and conditions defined in
 *  file 'LICENSE', which is part of this source code package.
 * ========================================================================= */
#include "Controller.h"
#include "Externs.h"
#include "Render.h"

#ifdef __cplusplus
#include <cassert>
#include <cstring>
#else
#include <assert.h>
#include <string.h>
#endif

#include <GL/glfw.h>

static void RenderFrame16(struct VIFController *controller);

/* ============================================================================
 *  RenderFrame: Draws a frame to the display.
 * ========================================================================= */
void
RenderFrame(struct VIFController *controller) {
  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  debug("== Rastering Frame ==");
  debugarg("Height:  [%u].", controller->renderArea.height);
  debugarg("Width:   [%u].", controller->renderArea.width);
  debugarg("X Start: [%u].", controller->renderArea.x.start);
  debugarg("X End:   [%u].", controller->renderArea.x.end);
  debugarg("Y Start: [%u].", controller->renderArea.y.start);
  debugarg("Y End:   [%u].", controller->renderArea.y.end);

  switch(controller->regs[VI_STATUS_REG] & 0x3) {
  case 0:
    break;

  case 1:
    assert(0 && "Attempted to use reversed frame type.");
    break;

  case 2:
    RenderFrame16(controller);
    break;

  case 3:
    assert(0 && "32-bit frame.");
    break;
  }

  glfwPollEvents();
  glfwSwapBuffers();
}

/* ============================================================================
 *  Renders a 16-bit frame.
 * ========================================================================= */
static void
RenderFrame16(struct VIFController *controller) {
  uint32_t offset = controller->regs[VI_ORIGIN_REG] & 0xFFFFFF;
  const uint8_t *buffer = BusGetRDRAMPointer(controller->bus) + offset;

  int hdiff = controller->renderArea.x.end - controller->renderArea.x.start;
  int vdiff = controller->renderArea.y.end - controller->renderArea.y.start;
  float hcoeff = (float)(controller->regs[VI_X_SCALE_REG] & 0xFFF) / (1 << 10);
  float vcoeff = (float)(controller->regs[VI_Y_SCALE_REG] & 0xFFF) / (1 << 10);
  unsigned hres = (hdiff * hcoeff);
  unsigned vres = (vdiff * vcoeff);

  int hskip = controller->regs[VI_WIDTH_REG] - hres;

  debugarg("H Res:   [%u].", hres);
  debugarg("V Res:   [%u].", vres);
  debugarg("H Skip:  [%d].", hskip);

  if (vdiff <= 0 || hdiff <= 0 || !offset)
    return;

  /* Hacky? */
  if (hres > 640) {
    hskip += (hres - 640);
    hres = 640;
  }

  if (vres > 480) {
    vres = 480;
  }

  glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA,
    controller->renderArea.width + hskip,
    controller->renderArea.height,
    0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, buffer);

  glBegin(GL_QUADS);
    glTexCoord2i(0, 0);
    glVertex2i(0, 0);
    glTexCoord2i(controller->renderArea.width - hskip, 0);
    glVertex2i(controller->renderArea.width - hskip, 0);
    glTexCoord2i(controller->renderArea.width - hskip, controller->renderArea.height);
    glVertex2i(controller->renderArea.width - hskip, controller->renderArea.height);
    glTexCoord2i(0, controller->renderArea.height);
    glVertex2i(0, controller->renderArea.height);
  glEnd();
}

/* ============================================================================
 *  ResetPerspective: Calculates the coordinates of the visible area.
 * ========================================================================= */
void
ResetPerspective(struct VIFController *controller) {
  struct RenderArea *renderArea = &controller->renderArea;

  /* Calculate the bounding positions. */
  renderArea->x.start = controller->regs[VI_H_START_REG] >> 16 & 0x3FF;
  renderArea->x.end = controller->regs[VI_H_START_REG] & 0x3FF;
  renderArea->y.start = controller->regs[VI_V_START_REG] >> 16 & 0x3FF;
  renderArea->y.end = controller->regs[VI_V_START_REG] & 0x3FF;

  renderArea->y.end /= 2;
  renderArea->y.start /= 2;

  /* Calculate the height and width. */
  renderArea->height = ((controller->regs[VI_Y_SCALE_REG] & 0xFFF) *
    (renderArea->y.end - renderArea->y.start)) / 0x400;

  renderArea->width = ((controller->regs[VI_X_SCALE_REG] & 0xFFF) *
    (renderArea->x.end - renderArea->x.start)) / 0x400;

  /* Catch impossible conditions. */
  renderArea->width = (renderArea->width > 640) ? 640 : renderArea->width;
  renderArea->height = (renderArea->height > 480) ? 480 : renderArea->height;

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, renderArea->width, renderArea->height, 0, 0, 1);
}


{'fraction_non_alphanumeric': 0.26069878023568327, 'fraction_numerical': 0.023568327475708084, 'mean_word_length': 4.611948955916473, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 137, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5403669', 'n_tokens_mistral': 3366, 'n_tokens_neox': 3067, 'n_words': 635}