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
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 generated
pygame.VIDEORESIZEevery time the window is resized - The event contains the new dimensions in the attributes
event.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 alone
pygame.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 uses
pygame.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
- Pygame documentation:pygame.display.set_mode()
- Pygame documentation:Pygame Events
- Pygame documentation:pygame.display.set_caption()
Educational Integrity
What I Understand Now
- Resizable windows in Pygame:The flag
pygame.RESIZABLEallows users to resize the window, and Pygame raises eventsVIDEORESIZEwhen this happens - Pygame Events:Events are handled in the event loop using
pygame.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 again
pygame.display.set_mode()with new dimensions to update the window surface - Auto scaling:The use of
pygame.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 management
VIDEORESIZEshould 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