⚠️ Clean-Room / Educational

This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.

Scalable Window and Title ViboyColor

Date:2025-12-30 StepID:0369 State: VERIFIED

Summary

Implemented the ability to resize the emulator window using the flagpygame.RESIZABLEinpygame.display.set_mode(). Changed window title from "Viboy Color" to "ViboyColor" for a more compact visual identity. Added event handlingpygame.VIDEORESIZEin the methodshandle_events()and_show_loading_screen()to dynamically update the window dimensions when the user resizes it. The rendering automatically adapts to the new size usingpygame.transform.scale().

Hardware Concept

Resizable Windows in Graphical Interfaces

In modern graphical applications, allowing users to resize windows is a standard feature that improves the user experience. This is especially useful for emulators, where users may want to adjust the window size based on their preferences or the size of their screen.

Pygame provides the flagpygame.RESIZABLEwhich allows the window to be resizable. When this flag is activated:

  • The user can drag the edges of the window to resize it
  • The event is generatedpygame.VIDEORESIZEevery time the window is resized
  • The event contains the new dimensions in the attributesevent.w(width) andevent.h(high)

Graphics Scaling

When the window is resized, the content must be scaled to fit the new size. In the emulator, the internal framebuffer has a fixed size 160x144 pixels (native Game Boy size), and this is scaled to the window dimensions usingpygame.transform.scale(). This method interpolates pixels to fit the content to the new size, maintaining the original aspect ratio when possible.

Note:Although the window is resizable, the emulator's content will be scaled to fill the window, which may result in distortion if the user makes the window very wide or very tall. To maintain the correct proportion, it would be necessary to calculate a scale factor that maintains the relationship 160:144, but for now any size is allowed to give flexibility to the user.

Implementation

The class was modifiedRendererinsrc/gpu/renderer.pyto make the window resizable and change the title.

Modifications in the Constructor (__init__)

The call was changed topygame.display.set_mode()to include the flagpygame.RESIZABLE:

# Before:
self.screen = pygame.display.set_mode((self.window_width, self.window_height))

# After:
self.screen = pygame.display.set_mode((self.window_width, self.window_height), pygame.RESIZABLE)

Changed window title from "Viboy Color" to "ViboyColor":

# Before:
pygame.display.set_caption("Viboy Color")

# After:
pygame.display.set_caption("ViboyColor")

Handling the VIDEORESIZE Event in handle_events()

Added event handlingpygame.VIDEORESIZEin the methodhandle_events()to update the window dimensions when the user resizes it:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        return False
    
    # Handle window resizing
    elif event.type == pygame.VIDEORESIZE:
        self.window_width = event.w
        self.window_height = event.h
        # Update window surface size
        self.screen = pygame.display.set_mode((self.window_width, self.window_height), pygame.RESIZABLE)

When the event is detectedVIDEORESIZE, the variables are updatedself.window_widthandself.window_heightwith the new dimensions, and is called againpygame.display.set_mode()with the new size to update the window surface.

Handling the VIDEORESIZE Event in _show_loading_screen()

Added the same event handlingpygame.VIDEORESIZEin the method_show_loading_screen()To maintain consistency during the loading screen:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
        break
    elif event.type == pygame.VIDEORESIZE:
        self.window_width = event.w
        self.window_height = event.h
        # Update window surface size
        self.screen = pygame.display.set_mode((self.window_width, self.window_height), pygame.RESIZABLE)
    elif event.type == pygame.KEYDOWN:
        if event.key == pygame.K_ESCAPE:
            running = False
            break

Design Decisions

  • RESIZABLE Flag:Used alonepygame.RESIZABLEwithout any other additional flags, maintaining simplicity
  • Dimensions update:Both internal variables and the window surface are updated to maintain consistency
  • Simplified title:Changed from "Viboy Color" to "ViboyColor" for a more compact and modern visual identity
  • Auto scaling:Existing rendering already usespygame.transform.scale(), so it automatically adapts to the new size

Affected Files

  • src/gpu/renderer.py- Added flagpygame.RESIZABLEinset_mode(), changed title to "ViboyColor", added handlingpygame.VIDEORESIZEinhandle_events()and_show_loading_screen()

Tests and Verification

The functionality was verified manually by running the emulator:

  • Visual verification:Confirmed that the window can be resized by dragging the edges
  • Window title:Confirmed that the title now shows "ViboyColor" instead of "Viboy Color"
  • Content adaptation:Confirmed that emulator content scales correctly when resizing the window
  • Loading screen:Confirmed that resizing also works during the loading screen
  • Icon:It was confirmed that the window icon still works correctly (it was already implemented previously)

Note:No additional unit tests were required as this is a UI functionality that is best verified visually.

Sources consulted

Educational Integrity

What I Understand Now

  • Resizable windows in Pygame:The flagpygame.RESIZABLEallows users to resize the window, and Pygame raises eventsVIDEORESIZEwhen this happens
  • Pygame Events:Events are handled in the event loop usingpygame.event.get(), and each event has a type and specific attributes depending on the type
  • Surface update:When the window is resized, it is necessary to call againpygame.display.set_mode()with new dimensions to update the window surface
  • Auto scaling:The use ofpygame.transform.scale()in existing rendering code allows content to automatically adapt to new window size

What remains to be confirmed

  • Whether it would be beneficial to keep the 160:144 aspect ratio when resizing the window (any ratio is currently allowed)
  • Whether there is any performance impact when resizing frequently (probably minimal)

Hypotheses and Observations

  • The title change to "ViboyColor" is more consistent with the project's modern visual identity
  • The ability to resize the window improves usability, especially on different sized screens
  • Event managementVIDEORESIZEshould be done in all places where events are handled to maintain consistency

Next Steps

  • [ ] Consider keeping the 160:144 aspect ratio when resizing (optional)
  • [ ] Continue with other UI improvements as required
  • [ ] Continue with the development of the emulator according to the roadmap