Add copyright message to gles_video
[gpsp.git] / video.c
diff --git a/video.c b/video.c
index ada3fea..4ea2696 100644 (file)
--- a/video.c
+++ b/video.c
@@ -18,6 +18,7 @@
  */
 
 #include "common.h"
+#define WANT_FONT_BITS
 #include "font.h"
 
 #ifdef PSP_BUILD
@@ -85,7 +86,14 @@ static void Ge_Finish_Callback(int id, void *arg)
 #define get_screen_pitch()                                                    \
   screen_pitch                                                                \
 
-#elif defined(WIZ_BUILD)
+#elif defined(POLLUX_BUILD)
+
+static u16 rot_buffer[240*4];
+static u32 rot_lines_total = 4;
+static u32 rot_line_count = 0;
+#ifdef WIZ_BUILD
+static char rot_msg_buff[64];
+#endif
 
 static u32 screen_offset = 0;
 static u16 *screen_pixels = NULL;
@@ -97,6 +105,16 @@ const u32 screen_pitch = 320;
 #define get_screen_pitch()                                                    \
   screen_pitch                                                                \
 
+#elif defined(PND_BUILD) || defined(RPI_BUILD)
+
+static u16 *screen_pixels = NULL;
+
+#define get_screen_pixels()                                                   \
+  screen_pixels                                                               \
+
+#define get_screen_pitch()                                                    \
+  resolution_width                                                            \
+
 #else
 
 #ifdef GP2X_BUILD
@@ -114,11 +132,11 @@ const u32 video_scale = 1;
 
 #endif
 
-void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
- u32 enable_flags, u32 dispcnt, u32 bldcnt, tile_layer_render_struct
+static void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
+ u32 enable_flags, u32 dispcnt, u32 bldcnt, const tile_layer_render_struct
  *layer_renderers);
-void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
- u32 enable_flags, u32 dispcnt, u32 bldcnt, bitmap_layer_render_struct
+static void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
+ u32 enable_flags, u32 dispcnt, u32 bldcnt, const bitmap_layer_render_struct
  *layer_renderers);
 
 #define no_op                                                                 \
@@ -996,23 +1014,18 @@ void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
 
 
 
-
-// Map widths and heights
-
-u32 map_widths[] = { 256, 512, 256, 512 };
-u32 map_heights[] = { 256, 256, 512, 512 };
+static const u32 map_widths[] = { 256, 512, 256, 512 };
 
 // Build text scanline rendering functions.
 
 #define render_scanline_text_builder(combine_op, alpha_op)                    \
-void render_scanline_text_##combine_op##_##alpha_op(u32 layer,                \
+static void render_scanline_text_##combine_op##_##alpha_op(u32 layer,         \
  u32 start, u32 end, void *scanline)                                          \
 {                                                                             \
   render_scanline_extra_variables_##combine_op##_##alpha_op(text);            \
   u32 bg_control = io_registers[REG_BG0CNT + layer];                          \
   u32 map_size = (bg_control >> 14) & 0x03;                                   \
   u32 map_width = map_widths[map_size];                                       \
-  u32 map_height = map_heights[map_size];                                     \
   u32 horizontal_offset =                                                     \
    (io_registers[REG_BG0HOFS + (layer * 2)] + start) % 512;                   \
   u32 vertical_offset = (io_registers[REG_VCOUNT] +                           \
@@ -1263,7 +1276,6 @@ void render_scanline_affine_##combine_op##_##alpha_op(u32 layer,              \
   u32 bg_control = io_registers[REG_BG0CNT + layer];                          \
   u32 current_pixel;                                                          \
   s32 source_x, source_y;                                                     \
-  u32 vcount = io_registers[REG_VCOUNT];                                      \
   u32 pixel_x, pixel_y;                                                       \
   u32 layer_offset = (layer - 2) * 8;                                         \
   s32 dx, dy;                                                                 \
@@ -1272,7 +1284,7 @@ void render_scanline_affine_##combine_op##_##alpha_op(u32 layer,              \
   u32 map_pitch = map_size + 4;                                               \
   u8 *map_base = vram + (((bg_control >> 8) & 0x1F) * (1024 * 2));            \
   u8 *tile_base = vram + (((bg_control >> 2) & 0x03) * (1024 * 16));          \
-  u8 *tile_ptr;                                                               \
+  u8 *tile_ptr = NULL;                                                        \
   u32 map_offset, last_map_offset = (u32)-1;                                  \
   u32 i;                                                                      \
   render_scanline_dest_##alpha_op *dest_ptr =                                 \
@@ -1460,13 +1472,11 @@ render_scanline_affine_builder(transparent, alpha);
 // Build bitmap scanline rendering functions.
 
 #define render_scanline_bitmap_builder(type, alpha_op, width, height)         \
-void render_scanline_bitmap_##type##_##alpha_op(u32 start, u32 end,           \
+static void render_scanline_bitmap_##type##_##alpha_op(u32 start, u32 end,    \
  void *scanline)                                                              \
 {                                                                             \
-  u32 bg_control = io_registers[REG_BG2CNT];                                  \
   u32 current_pixel;                                                          \
   s32 source_x, source_y;                                                     \
-  u32 vcount = io_registers[REG_VCOUNT];                                      \
   s32 pixel_x, pixel_y;                                                       \
                                                                               \
   s32 dx = (s16)io_registers[REG_BG2PA];                                      \
@@ -1527,7 +1537,7 @@ render_scanline_bitmap_builder(mode5, normal, 160, 128);
 
 // Structs containing functions to render the layers for each mode, for
 // each render type.
-tile_layer_render_struct tile_mode_renderers[3][4] =
+static const tile_layer_render_struct tile_mode_renderers[3][4] =
 {
   {
     tile_layer_render_functions(text), tile_layer_render_functions(text),
@@ -1543,7 +1553,7 @@ tile_layer_render_struct tile_mode_renderers[3][4] =
   }
 };
 
-bitmap_layer_render_struct bitmap_mode_renderers[3] =
+static const bitmap_layer_render_struct bitmap_mode_renderers[3] =
 {
   bitmap_layer_render_functions(mode3),
   bitmap_layer_render_functions(mode4),
@@ -1552,11 +1562,11 @@ bitmap_layer_render_struct bitmap_mode_renderers[3] =
 
 
 #define render_scanline_layer_functions_tile()                                \
-  tile_layer_render_struct *layer_renderers =                                 \
+  const tile_layer_render_struct *layer_renderers =                           \
    tile_mode_renderers[dispcnt & 0x07]                                        \
 
 #define render_scanline_layer_functions_bitmap()                              \
-  bitmap_layer_render_struct *layer_renderers =                               \
+  const bitmap_layer_render_struct *layer_renderers =                         \
    bitmap_mode_renderers + ((dispcnt & 0x07) - 3)                             \
 
 
@@ -1568,8 +1578,8 @@ bitmap_layer_render_struct bitmap_mode_renderers[3] =
   + (tile_size_##color_depth * ((obj_width - 8) / 8))                         \
 
 
-// Adjust the obj's starting point if it goes too far off the left edge of    \
-// the screen.                                                                \
+// Adjust the obj's starting point if it goes too far off the left edge of
+// the screen.
 
 #define obj_tile_right_offset_noflip(color_depth)                             \
   tile_ptr += (partial_tile_offset / 8) * tile_size_##color_depth             \
@@ -1829,14 +1839,13 @@ bitmap_layer_render_struct bitmap_mode_renderers[3] =
 
 #define obj_render_affine(combine_op, color_depth, alpha_op, map_space)       \
 {                                                                             \
-  s16 *params = oam_ram + (((obj_attribute_1 >> 9) & 0x1F) * 16);             \
+  s16 *params = (s16 *)oam_ram + (((obj_attribute_1 >> 9) & 0x1F) * 16);      \
   s32 dx = params[3];                                                         \
   s32 dmx = params[7];                                                        \
   s32 dy = params[11];                                                        \
   s32 dmy = params[15];                                                       \
   s32 source_x, source_y;                                                     \
   s32 tile_x, tile_y;                                                         \
-  u32 tile_offset;                                                            \
   u32 tile_map_offset;                                                        \
   s32 middle_x;                                                               \
   s32 middle_y;                                                               \
@@ -1895,12 +1904,14 @@ bitmap_layer_render_struct bitmap_mode_renderers[3] =
   }                                                                           \
 }                                                                             \
 
-u32 obj_width_table[] = { 8, 16, 32, 64, 16, 32, 32, 64, 8, 8, 16, 32 };
-u32 obj_height_table[] = { 8, 16, 32, 64, 8, 8, 16, 32, 16, 32, 32, 64 };
+static const u32 obj_width_table[] =
+  { 8, 16, 32, 64, 16, 32, 32, 64, 8, 8, 16, 32 };
+static const u32 obj_height_table[] =
+  { 8, 16, 32, 64, 8, 8, 16, 32, 16, 32, 32, 64 };
 
-u8 obj_priority_list[5][160][128];
-u32 obj_priority_count[5][160];
-u32 obj_alpha_count[160];
+static u8 obj_priority_list[5][160][128];
+static u32 obj_priority_count[5][160];
+static u32 obj_alpha_count[160];
 
 
 // Build obj rendering functions
@@ -1919,11 +1930,11 @@ u32 obj_alpha_count[160];
 
 
 #define render_scanline_obj_extra_variables_color()                           \
-  u32 dest;                                                                   \
   u32 pixel_combine = color_combine_mask(4) | (1 << 8)                        \
 
 #define render_scanline_obj_extra_variables_alpha_obj(map_space)              \
   render_scanline_obj_extra_variables_color();                                \
+  u32 dest;                                                                   \
   if((pixel_combine & 0x00000200) == 0)                                       \
   {                                                                           \
     render_scanline_obj_color32_##map_space(priority, start, end, scanline);  \
@@ -1938,7 +1949,8 @@ u32 obj_alpha_count[160];
 
 #define render_scanline_obj_extra_variables_partial_alpha(map_space)          \
   render_scanline_obj_extra_variables_color();                                \
-  u32 base_pixel_combine = pixel_combine                                      \
+  u32 base_pixel_combine = pixel_combine;                                     \
+  u32 dest                                                                    \
 
 #define render_scanline_obj_extra_variables_copy(type)                        \
   u32 bldcnt = io_registers[REG_BLDCNT];                                      \
@@ -2048,7 +2060,7 @@ u32 obj_alpha_count[160];
 
 #define render_scanline_obj_builder(combine_op, alpha_op, map_space,          \
  partial_alpha_op)                                                            \
-void render_scanline_obj_##alpha_op##_##map_space(u32 priority,               \
+static void render_scanline_obj_##alpha_op##_##map_space(u32 priority,        \
  u32 start, u32 end, render_scanline_dest_##alpha_op *scanline)               \
 {                                                                             \
   render_scanline_obj_extra_variables_##alpha_op(map_space);                  \
@@ -2112,7 +2124,7 @@ render_scanline_obj_builder(copy, copy_bitmap, 2D, no_partial_alpha);
 
 
 
-void order_obj(u32 video_mode)
+static void order_obj(u32 video_mode)
 {
   s32 obj_num, priority, row;
   s32 obj_x, obj_y;
@@ -2120,14 +2132,8 @@ void order_obj(u32 video_mode)
   s32 obj_width, obj_height;
   u32 obj_priority;
   u32 obj_attribute_0, obj_attribute_1, obj_attribute_2;
-  s32 vcount = io_registers[REG_VCOUNT];
-  u32 partial_tile_run, partial_tile_offset;
-  u32 pixel_run;
   u32 current_count;
   u16 *oam_ptr = oam_ram + 508;
-  u16 *dest_ptr;
-  u8 *tile_base = vram + 0x10000;
-  u8 *tile_ptr;
 
   for(priority = 0; priority < 5; priority++)
   {
@@ -2219,7 +2225,7 @@ void order_obj(u32 video_mode)
 u32 layer_order[16];
 u32 layer_count;
 
-u32 order_layers(u32 layer_flags)
+static void order_layers(u32 layer_flags)
 {
   s32 priority, layer_number;
   layer_count = 0;
@@ -2264,7 +2270,7 @@ u32 order_layers(u32 layer_flags)
 #define fill_line_color_color32()                                             \
 
 #define fill_line_builder(type)                                               \
-void fill_line_##type(u16 color, render_scanline_dest_##type *dest_ptr,       \
+static void fill_line_##type(u16 color, render_scanline_dest_##type *dest_ptr,\
  u32 start, u32 end)                                                          \
 {                                                                             \
   fill_line_color_##type();                                                   \
@@ -2398,7 +2404,7 @@ fill_line_builder(color32);
 
 #ifdef RENDER_COLOR16_NORMAL
 
-#ifndef GP2X_BUILD
+#ifndef ARM_ARCH
 
 void expand_normal(u16 *screen_ptr, u32 start, u32 end)
 {
@@ -2427,7 +2433,10 @@ void expand_normal(u16 *screen_ptr, u32 start, u32 end)
 #endif
 
 
-#ifndef GP2X_BUILD
+void expand_blend(u32 *screen_src_ptr, u16 *screen_dest_ptr,
+ u32 start, u32 end);
+
+#ifndef ARM_ARCH
 
 void expand_blend(u32 *screen_src_ptr, u16 *screen_dest_ptr,
  u32 start, u32 end)
@@ -2461,7 +2470,7 @@ void expand_blend(u32 *screen_src_ptr, u16 *screen_dest_ptr,
 
 // Blend scanline with white.
 
-void expand_darken(u16 *screen_src_ptr, u16 *screen_dest_ptr,
+static void expand_darken(u16 *screen_src_ptr, u16 *screen_dest_ptr,
  u32 start, u32 end)
 {
   u32 pixel_top;
@@ -2477,7 +2486,7 @@ void expand_darken(u16 *screen_src_ptr, u16 *screen_dest_ptr,
 
 // Blend scanline with black.
 
-void expand_brighten(u16 *screen_src_ptr, u16 *screen_dest_ptr,
+static void expand_brighten(u16 *screen_src_ptr, u16 *screen_dest_ptr,
  u32 start, u32 end)
 {
   u32 pixel_top;
@@ -2499,7 +2508,7 @@ void expand_brighten(u16 *screen_src_ptr, u16 *screen_dest_ptr,
 // Expand scanline such that if both top and bottom pass it's alpha,
 // if only top passes it's as specified, and if neither pass it's normal.
 
-void expand_darken_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
+static void expand_darken_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
  u32 start, u32 end)
 {
   s32 blend = 16 - (io_registers[REG_BLDY] & 0x1F);
@@ -2523,7 +2532,7 @@ void expand_darken_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
 }
 
 
-void expand_brighten_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
+static void expand_brighten_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
  u32 start, u32 end)
 {
   s32 blend = io_registers[REG_BLDY] & 0x1F;
@@ -2758,7 +2767,7 @@ void expand_brighten_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_ptr,
 
 // Renders an entire scanline from 0 to 240, based on current color mode.
 
-void render_scanline_tile(u16 *scanline, u32 dispcnt)
+static void render_scanline_tile(u16 *scanline, u32 dispcnt)
 {
   u32 current_layer;
   u32 layer_order_pos;
@@ -2769,9 +2778,8 @@ void render_scanline_tile(u16 *scanline, u32 dispcnt)
    render_condition_alpha, render_condition_fade, 0, 240);
 }
 
-void render_scanline_bitmap(u16 *scanline, u32 dispcnt)
+static void render_scanline_bitmap(u16 *scanline, u32 dispcnt)
 {
-  u32 bldcnt = io_registers[REG_BLDCNT];
   render_scanline_layer_functions_bitmap();
   u32 current_layer;
   u32 layer_order_pos;
@@ -2890,8 +2898,8 @@ void render_scanline_bitmap(u16 *scanline, u32 dispcnt)
 // Render all of the BG and OBJ in a tiled scanline from start to end ONLY if
 // enable_flag allows that layer/OBJ. Also conditionally render color effects.
 
-void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
- u32 enable_flags, u32 dispcnt, u32 bldcnt, tile_layer_render_struct
+static void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
+ u32 enable_flags, u32 dispcnt, u32 bldcnt, const tile_layer_render_struct
  *layer_renderers)
 {
   u32 current_layer;
@@ -2907,8 +2915,8 @@ void render_scanline_conditional_tile(u32 start, u32 end, u16 *scanline,
 // Render the BG and OBJ in a bitmap scanline from start to end ONLY if
 // enable_flag allows that layer/OBJ. Also conditionally render color effects.
 
-void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
- u32 enable_flags, u32 dispcnt, u32 bldcnt, bitmap_layer_render_struct
+static void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
+ u32 enable_flags, u32 dispcnt, u32 bldcnt, const bitmap_layer_render_struct
  *layer_renderers)
 {
   u32 current_layer;
@@ -2952,7 +2960,7 @@ void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
 #define window_coords(window_number)                                          \
   u32 window_##window_number##_x1, window_##window_number##_x2;               \
   u32 window_##window_number##_y1, window_##window_number##_y2;               \
-  u32 window_##window_number##_enable;                                        \
+  u32 window_##window_number##_enable = 0;                                    \
   window_##window_number##_y1 =                                               \
    io_registers[REG_WIN##window_number##V] >> 8;                              \
   window_##window_number##_y2 =                                               \
@@ -3163,7 +3171,7 @@ void render_scanline_conditional_bitmap(u32 start, u32 end, u16 *scanline,
   }                                                                           \
 
 #define render_scanline_window_builder(type)                                  \
-void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
+static void render_scanline_window_##type(u16 *scanline, u32 dispcnt)         \
 {                                                                             \
   u32 vcount = io_registers[REG_VCOUNT];                                      \
   u32 winout = io_registers[REG_WINOUT];                                      \
@@ -3201,7 +3209,6 @@ void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
     /* Just OBJ windows */                                                    \
     case 0x04:                                                                \
     {                                                                         \
-      u32 window_obj_enable = winout >> 8;                                    \
       render_window_clip_obj(type, 0, 240);                                   \
       break;                                                                  \
     }                                                                         \
@@ -3209,7 +3216,6 @@ void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
     /* Window 0 and OBJ window */                                             \
     case 0x05:                                                                \
     {                                                                         \
-      u32 window_obj_enable = winout >> 8;                                    \
       u32 winin = io_registers[REG_WININ];                                    \
       window_coords(0);                                                       \
       render_window_multi(type, 0, obj);                                      \
@@ -3219,7 +3225,6 @@ void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
     /* Window 1 and OBJ window */                                             \
     case 0x06:                                                                \
     {                                                                         \
-      u32 window_obj_enable = winout >> 8;                                    \
       u32 winin = io_registers[REG_WININ];                                    \
       window_coords(1);                                                       \
       render_window_multi(type, 1, obj);                                      \
@@ -3229,7 +3234,6 @@ void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
     /* Window 0, 1, and OBJ window */                                         \
     case 0x07:                                                                \
     {                                                                         \
-      u32 window_obj_enable = winout >> 8;                                    \
       u32 winin = io_registers[REG_WININ];                                    \
       window_coords(0);                                                       \
       window_coords(1);                                                       \
@@ -3242,7 +3246,7 @@ void render_scanline_window_##type(u16 *scanline, u32 dispcnt)                \
 render_scanline_window_builder(tile);
 render_scanline_window_builder(bitmap);
 
-u32 active_layers[6] = { 0x1F, 0x17, 0x1C, 0x14, 0x14, 0x14 };
+static const u32 active_layers[6] = { 0x1F, 0x17, 0x1C, 0x14, 0x14, 0x14 };
 
 u32 small_resolution_width = 240;
 u32 small_resolution_height = 160;
@@ -3252,11 +3256,9 @@ void update_scanline()
 {
   u32 pitch = get_screen_pitch();
   u32 dispcnt = io_registers[REG_DISPCNT];
-  u32 display_flags = (dispcnt >> 8) & 0x1F;
   u32 vcount = io_registers[REG_VCOUNT];
   u16 *screen_offset = get_screen_pixels() + (vcount * pitch);
   u32 video_mode = dispcnt & 0x07;
-  u32 current_layer;
 
   // If OAM has been modified since the last scanline has been updated then
   // reorder and reprofile the OBJ lists.
@@ -3271,6 +3273,28 @@ void update_scanline()
   if(skip_next_frame)
     return;
 
+#ifdef WIZ_BUILD
+  if (screen_scale == unscaled_rot || screen_scale == scaled_aspect_rot)
+  {
+    if (rot_line_count == rot_lines_total)
+    {
+      rot_line_count = 0;
+      if (vcount - rot_lines_total < FONT_HEIGHT && rot_msg_buff[0])
+      {
+        print_string_ext(rot_msg_buff, 0xFFFF, 0x0000, 0, 0,
+          rot_buffer, 240, 0, vcount - rot_lines_total, rot_lines_total);
+        if (vcount >= FONT_HEIGHT)
+          rot_msg_buff[0] = 0;
+      }
+      if (screen_scale == unscaled_rot)
+        do_rotated_blit(gpsp_gp2x_screen, rot_buffer, vcount);
+      else
+        upscale_aspect_row(gpsp_gp2x_screen, rot_buffer, vcount/3);
+    }
+    screen_offset = &rot_buffer[rot_line_count++ * 240];
+  }
+#endif
+
   // If the screen is in in forced blank draw pure white.
   if(dispcnt & 0x80)
   {
@@ -3334,20 +3358,43 @@ void flip_screen()
   }
 }
 
-#elif defined(WIZ_BUILD)
+#elif defined(POLLUX_BUILD)
 
 void flip_screen()
 {
-  if((screen_scale == scaled_aspect) &&
-   (resolution_width == small_resolution_width) &&
+  if((resolution_width == small_resolution_width) &&
    (resolution_height == small_resolution_height))
   {
-    upscale_aspect(gpsp_gp2x_screen, screen_pixels);
+    switch(screen_scale)
+    {
+      case unscaled:
+        break;
+      case scaled_aspect:
+        upscale_aspect(gpsp_gp2x_screen, screen_pixels);
+        break;
+      case unscaled_rot:
+        do_rotated_blit(gpsp_gp2x_screen, rot_buffer, 160);
+        rot_line_count = 0;
+        goto no_clean;
+      case scaled_aspect_rot:
+        rot_line_count = 0;
+        goto no_clean;
+    }
   }
+  warm_cache_op_all(WOP_D_CLEAN);
+
+no_clean:
   pollux_video_flip();
   screen_pixels = (u16 *)gpsp_gp2x_screen + screen_offset;
 }
 
+#elif defined(PND_BUILD) || defined(RPI_BUILD)
+
+void flip_screen()
+{
+  screen_pixels = fb_flip_screen();
+}
+
 #else
 
 #define integer_scale_copy_2()                                                \
@@ -3423,26 +3470,37 @@ void flip_screen()
   }
 #ifdef GP2X_BUILD
   {
-    if((screen_scale == unscaled) &&
-     (resolution_width == small_resolution_width) &&
-     (resolution_height == small_resolution_height))
-    {
-      SDL_Rect srect = {0, 0, 240, 160};
-      SDL_Rect drect = {40, 40, 240, 160};
-      SDL_BlitSurface(screen, &srect, hw_screen, &drect);
-    }
-    else if((screen_scale == scaled_aspect) &&
-     (resolution_width == small_resolution_width) &&
+    if((resolution_width == small_resolution_width) &&
      (resolution_height == small_resolution_height))
     {
-      SDL_Rect drect = {0, 10, 0, 0};
-      SDL_BlitSurface(screen, NULL, hw_screen, &drect);
-    }
-    else
-    {
-      SDL_BlitSurface(screen, NULL, hw_screen, NULL);
+      switch (screen_scale)
+      {
+        case unscaled:
+        {
+          SDL_Rect srect = {0, 0, 240, 160};
+          SDL_Rect drect = {40, 40, 240, 160};
+          warm_cache_op_all(WOP_D_CLEAN);
+          SDL_BlitSurface(screen, &srect, hw_screen, &drect);
+          return;
+        }
+        case scaled_aspect:
+        {
+          SDL_Rect drect = {0, 10, 0, 0};
+          warm_cache_op_all(WOP_D_CLEAN);
+          SDL_BlitSurface(screen, NULL, hw_screen, &drect);
+          return;
+        }
+        case scaled_aspect_sw:
+        {
+          upscale_aspect(hw_screen->pixels, get_screen_pixels());
+          return;
+        }
+        case fullscreen:
+          break;
+      }
     }
     warm_cache_op_all(WOP_D_CLEAN);
+    SDL_BlitSurface(screen, NULL, hw_screen, NULL);
   }
 #else
   SDL_Flip(screen);
@@ -3546,7 +3604,7 @@ void init_video()
   GE_CMD(NOP, 0);
 }
 
-#elif defined(WIZ_BUILD)
+#elif defined(WIZ_BUILD) || defined(PND_BUILD) || defined (RPI_BUILD)
 
 void init_video()
 {
@@ -3579,6 +3637,7 @@ void init_video()
 video_scale_type screen_scale = scaled_aspect;
 video_scale_type current_scale = scaled_aspect;
 video_filter_type screen_filter = filter_bilinear;
+video_filter_type2 screen_filter2 = filter2_none;
 
 
 #ifdef PSP_BUILD
@@ -3680,7 +3739,7 @@ void clear_screen(u16 color)
   sceGuSync(0, 0); */
 }
 
-#elif defined(WIZ_BUILD)
+#elif defined(POLLUX_BUILD)
 
 void video_resolution_large()
 {
@@ -3691,20 +3750,40 @@ void video_resolution_large()
   fb_use_buffers(1);
   flip_screen();
   clear_screen(0);
+  wiz_lcd_set_portrait(0);
 }
 
 void video_resolution_small()
 {
-  if(screen_scale == scaled_aspect)
-    screen_offset = 320*(80 - 14) + 80;
-  else
-    screen_offset = 320*40 + 40;
-  resolution_width = 240;
-  resolution_height = 160;
-
   fb_use_buffers(4);
+
+  switch (screen_scale)
+  {
+    case unscaled:
+      screen_offset = 320*40 + 40;
+      wiz_lcd_set_portrait(0);
+      break;
+    case scaled_aspect:
+      screen_offset = 320*(80 - 14) + 80;
+      wiz_lcd_set_portrait(0);
+      break;
+    case unscaled_rot:
+      wiz_lcd_set_portrait(1);
+      rot_lines_total = 4;
+      rot_line_count = 0;
+      break;
+    case scaled_aspect_rot:
+      wiz_lcd_set_portrait(1);
+      rot_lines_total = 3;
+      rot_line_count = 0;
+      break;
+  }
+
   flip_screen();
   clear_screen(0);
+
+  resolution_width = 240;
+  resolution_height = 160;
 }
 
 void set_gba_resolution(video_scale_type scale)
@@ -3721,6 +3800,46 @@ void clear_screen(u16 color)
     *p++ = col;
 }
 
+#elif defined(PND_BUILD) || defined(RPI_BUILD)
+
+void video_resolution_large()
+{
+#if defined (RPI_BUILD)
+  resolution_width = 480;
+#else
+  resolution_width = 400;
+#endif
+  resolution_height = 272;
+
+  fb_set_mode(resolution_width, resolution_height, 1, 15, screen_filter, screen_filter2);
+  flip_screen();
+  clear_screen(0);
+}
+
+void video_resolution_small()
+{
+  resolution_width = 240;
+  resolution_height = 160;
+
+  fb_set_mode(resolution_width, resolution_height, 3, screen_scale, screen_filter, screen_filter2);
+  flip_screen();
+  clear_screen(0);
+}
+
+void set_gba_resolution(video_scale_type scale)
+{
+  screen_scale = scale;
+}
+
+void clear_screen(u16 color)
+{
+  u32 col = ((u32)color << 16) | color;
+  u32 *p = (u32 *)get_screen_pixels();
+  int c = resolution_width * resolution_height / 2;
+  while (c-- > 0)
+    *p++ = col;
+}
+
 #else
 
 void video_resolution_large()
@@ -3755,7 +3874,7 @@ void video_resolution_small()
   SDL_GP2X_AllowGfxMemory(NULL, 0);
 
   w = 320; h = 240;
-  if (screen_scale != unscaled)
+  if (screen_scale == scaled_aspect || screen_scale == fullscreen)
   {
     w = small_resolution_width * video_scale;
     h = small_resolution_height * video_scale;
@@ -3763,9 +3882,12 @@ void video_resolution_small()
   if (screen_scale == scaled_aspect) h += 20;
   hw_screen = SDL_SetVideoMode(w, h, 16, SDL_HWSURFACE);
 
+  w = small_resolution_width * video_scale;
+  if (screen_scale == scaled_aspect_sw)
+    w = 320;
   screen = SDL_CreateRGBSurface(SDL_HWSURFACE,
-   small_resolution_width * video_scale, small_resolution_height *
-   video_scale, 16, 0xFFFF, 0xFFFF, 0xFFFF, 0);
+   w, small_resolution_height * video_scale,
+   16, 0xFFFF, 0xFFFF, 0xFFFF, 0);
 
   SDL_ShowCursor(0);
 
@@ -3783,15 +3905,8 @@ void set_gba_resolution(video_scale_type scale)
   if(screen_scale != scale)
   {
     screen_scale = scale;
-    switch(scale)
-    {
-      case unscaled:
-      case scaled_aspect:
-      case fullscreen:
-        small_resolution_width = 240 * video_scale;
-        small_resolution_height = 160 * video_scale;
-        break;
-    }
+    small_resolution_width = 240 * video_scale;
+    small_resolution_height = 160 * video_scale;
   }
 }
 
@@ -3825,34 +3940,33 @@ void blit_to_screen(u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y)
   u32 pitch = get_screen_pitch();
   u16 *dest_ptr = get_screen_pixels() + dest_x + (dest_y * pitch);
 
+  s32 w1 = dest_x + w > pitch ? pitch - dest_x : w;
   u16 *src_ptr = src;
-  u32 line_skip = pitch - w;
-  u32 x, y;
+  s32 x, y;
 
   for(y = 0; y < h; y++)
   {
-    for(x = 0; x < w; x++, src_ptr++, dest_ptr++)
+    for(x = 0; x < w1; x++)
     {
-      *dest_ptr = *src_ptr;
+      dest_ptr[x] = src_ptr[x];
     }
-    dest_ptr += line_skip;
+    src_ptr += w;
+    dest_ptr += pitch;
   }
 }
 
 void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
- u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad)
+ u32 x, u32 y, void *_dest_ptr, u32 pitch, u32 pad, u32 h_offset, u32 height)
 {
   u16 *dest_ptr = (u16 *)_dest_ptr + (y * pitch) + x;
   u8 current_char = str[0];
   u32 current_row;
   u32 glyph_offset;
-  u32 i = 0, i2, i3;
+  u32 i = 0, i2, i3, h;
   u32 str_index = 1;
   u32 current_x = x;
 
-
-  /* EDIT */
-  if(y + FONT_HEIGHT > resolution_height)
+  if(y + height > resolution_height)
       return;
 
   while(current_char)
@@ -3867,7 +3981,8 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
     {
       glyph_offset = _font_offset[current_char];
       current_x += FONT_WIDTH;
-      for(i2 = 0; i2 < FONT_HEIGHT; i2++, glyph_offset++)
+      glyph_offset += h_offset;
+      for(i2 = h_offset, h = 0; i2 < FONT_HEIGHT && h < height; i2++, h++, glyph_offset++)
       {
         current_row = _font_bits[glyph_offset];
         for(i3 = 0; i3 < FONT_WIDTH; i3++)
@@ -3880,7 +3995,7 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
         }
         dest_ptr += (pitch - FONT_WIDTH);
       }
-      dest_ptr = dest_ptr - (pitch * FONT_HEIGHT) + FONT_WIDTH;
+      dest_ptr = dest_ptr - (pitch * h) + FONT_WIDTH;
     }
 
     i++;
@@ -3909,15 +4024,24 @@ void print_string_ext(const char *str, u16 fg_color, u16 bg_color,
 void print_string(const char *str, u16 fg_color, u16 bg_color,
  u32 x, u32 y)
 {
+#ifdef WIZ_BUILD
+  if ((screen_scale == unscaled_rot || screen_scale == scaled_aspect_rot) &&
+   (resolution_width == small_resolution_width) &&
+   (resolution_height == small_resolution_height))
+  {
+    snprintf(rot_msg_buff, sizeof(rot_msg_buff), "%s", str);
+    return;
+  }
+#endif
   print_string_ext(str, fg_color, bg_color, x, y, get_screen_pixels(),
-   get_screen_pitch(), 0);
+   get_screen_pitch(), 0, 0, FONT_HEIGHT);
 }
 
 void print_string_pad(const char *str, u16 fg_color, u16 bg_color,
  u32 x, u32 y, u32 pad)
 {
   print_string_ext(str, fg_color, bg_color, x, y, get_screen_pixels(),
-   get_screen_pitch(), pad);
+   get_screen_pitch(), pad, 0, FONT_HEIGHT);
 }
 
 u32 debug_cursor_x = 0;