00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <nds.h>
00021 #include "types.h"
00022 #include "graphics.h"
00023
00024 #include "kanji_bg.h"
00025 #include "goi_bg.h"
00026 #include "splash_main_bg.h"
00027 #include "cards_options_sub_bg.h"
00028 #include "kanji_choose_options_sub_bg.h"
00029 #include "vertical_textboxes_choose_options_bg.h"
00030 #include "main_menu_bg.h"
00031 #include "options_grade_strokes_romaji_sub_bg.h"
00032 #include "options_romaji_sub_bg.h"
00033
00034 using namespace Types;
00035 using namespace Graphics;
00036
00038 static const u16 rmask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4);
00040 static const u16 gmask = BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9);
00042 static const u16 bmask = BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14);
00043
00045 inline u8 red_color (u16 color)
00046 {
00047 return (color & rmask);
00048 }
00050 inline u8 green_color (u16 color)
00051 {
00052 return (color & gmask) >> 5;
00053 }
00055 inline u8 blue_color (u16 color)
00056 {
00057 return (color & bmask) >> 10;
00058 }
00059
00061 static const u16 TRANSPARENT_COLOR = 32768;
00062
00064 u16 black_color_main;
00066 u16 gray_color_main;
00068 u16 black_color_sub;
00070 u16 gray_color_sub;
00071
00074 inline u16 convert_color(u8 incolor, Screen::selector screen)
00075 {
00076 u16 outcolor;
00077 if (incolor > 180)
00078 outcolor = (screen == Screen::MAIN) ? black_color_main : black_color_sub;
00079 else if (incolor > 128)
00080 outcolor = (screen == Screen::MAIN) ? gray_color_main : gray_color_sub;
00081 else
00082 outcolor = TRANSPARENT_COLOR;
00083 return outcolor;
00084 }
00085
00096 void Graphics::FactorizePalette (const u16* src_palette, u16* dst_palette,
00097 int palette_size, u8 factor,
00098 ColorTransformation::mode trans)
00099 {
00100 palette_size >>= 1;
00101 if (trans == ColorTransformation::LIGHTER)
00102 for (int i = 0; i < palette_size; ++i)
00103 {
00104 u16 color = src_palette[i];
00105 dst_palette[i] = RGB15(red_color(color) * factor >> 8,
00106 green_color(color) * factor >> 8,
00107 blue_color(color) * factor >> 8);
00108 }
00109 else
00110 for (int i = 0; i < palette_size; ++i)
00111 {
00112 u16 color = src_palette[i];
00113 dst_palette[i] = RGB15(red_color(color) * (255 - factor) >> 8,
00114 green_color(color) * (255 - factor) >> 8,
00115 blue_color(color) * (255 - factor) >> 8);
00116 }
00117 }
00118
00129 void Graphics::SplashImage (const unsigned int* bitmap,
00130 const unsigned short* palette,
00131 Screen::selector screen, int bgid, u8 effect)
00132 {
00133 unsigned short* dst_palette;
00134 dmaCopy(bitmap, bgGetGfxPtr(bgid), SCREEN_WIDTH*SCREEN_HEIGHT);
00135 if (screen == Screen::MAIN)
00136 dst_palette = BG_PALETTE;
00137 else
00138 dst_palette = BG_PALETTE_SUB;
00139
00140 if (effect & SplashEffect::APPEAR)
00141 for (int i = 0; i < 256; i+=2)
00142 {
00143 FactorizePalette (palette, dst_palette, 256*2, i,
00144 ColorTransformation::LIGHTER);
00145 swiWaitForVBlank();
00146 }
00147 if (effect & SplashEffect::DISSOLVE)
00148 for (int i = 0; i < 256; i+=2)
00149 {
00150 FactorizePalette (palette, dst_palette, 256*2, i,
00151 ColorTransformation::DARKER);
00152 swiWaitForVBlank();
00153 }
00154 }
00155
00167 void Graphics::PrintBitmap (int x, int y, int width, int height,
00168 const unsigned int* bitmap,
00169 unsigned short key_color, int bgid,
00170 Screen::selector screen)
00171 {
00172 u16* video_buffer = bgGetGfxPtr(bgid);
00173
00174
00175 int key_color_index = FindColor (key_color, screen);
00176
00177 for (int image_y = 0; image_y < height; ++image_y)
00178 {
00179 int pixel_index_normal = image_y * width;
00180 for (int image_x = 0; image_x < width; image_x+=2, pixel_index_normal+=2)
00181 {
00182 bool print_pixel0 = true, print_pixel1 = true;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 int pixel_index_inverted = pixel_index_normal -
00195 (pixel_index_normal & 3) + (((pixel_index_normal & 3) + 2) & 3);
00196
00197 int pixel0 =
00198 ( (bitmap [(pixel_index_inverted >> 2)] &
00199 (0xFF000000 >> ((pixel_index_inverted & 3)<<3))
00200 ) >> ((3-(pixel_index_inverted & 3) << 3 ));
00201 if (pixel0 == key_color_index) print_pixel0 = false;
00202
00203 ++pixel_index_inverted;
00204
00205 int pixel1 =
00206 ( (bitmap [(pixel_index_inverted >> 2)] &
00207 (0xFF000000 >> ((pixel_index_inverted & 3)<<3))
00208 ) >> ((3-(pixel_index_inverted & 3)) << 3 ));
00209
00210 if (pixel1 == key_color_index) print_pixel1 = false;
00211
00212 int video_index = (image_y + y)*128 + (image_x + x)/2;
00213
00214 if (print_pixel0)
00215
00216 video_buffer[video_index] = (pixel0 << 8) |
00217 (video_buffer[video_index] & 0x00FF);
00218
00219 if (print_pixel1)
00220
00221 video_buffer[video_index] = pixel1 |
00222 (video_buffer[video_index] & 0xFF00);
00223 }
00224 }
00225 }
00226
00246 void Graphics::PrintBitmapRegion (int dst_x, int dst_y, int region_x,
00247 int region_y, int region_width,
00248 int region_height, int bmp_width,
00249 int bmp_height,
00250 const unsigned int* bitmap,
00251 unsigned short key_color,
00252 int bgid,
00253 Screen::selector screen,
00254 bool use_key_color)
00255 {
00256 u16* video_buffer = bgGetGfxPtr(bgid);
00257
00258
00259 int key_color_index = 0;
00260 if (use_key_color)
00261 key_color_index = FindColor (key_color, screen);
00262
00263 for (int image_y = 0; image_y < region_height; ++image_y)
00264 {
00265 int pixel_index_normal = (image_y+region_y) * bmp_width + region_x;
00266 for (int image_x = 0; image_x < region_width; image_x+=2, pixel_index_normal+=2)
00267 {
00268 bool print_pixel0 = true, print_pixel1 = true;
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 int pixel_index_inverted = pixel_index_normal -
00281 (pixel_index_normal & 3) + (((pixel_index_normal & 3) + 2) & 3);
00282
00283 int pixel0 =
00284 ( (bitmap [(pixel_index_inverted >> 2)] &
00285 (0xFF000000 >> ((pixel_index_inverted & 3)<<3))
00286 ) >> ((3-(pixel_index_inverted & 3) << 3 ));
00287 if (use_key_color && pixel0 == key_color_index) print_pixel0 = false;
00288
00289 ++pixel_index_inverted;
00290
00291 int pixel1 =
00292 ( (bitmap [(pixel_index_inverted >> 2)] &
00293 (0xFF000000 >> ((pixel_index_inverted & 3)<<3))
00294 ) >> ((3-(pixel_index_inverted & 3)) << 3 ));
00295
00296 if (use_key_color && pixel1 == key_color_index) print_pixel1 = false;
00297
00298 int video_index = (image_y + dst_y)*128 + (image_x + dst_x)/2;
00299
00300 if (print_pixel0)
00301
00302 video_buffer[video_index] = (pixel0 << 8) |
00303 (video_buffer[video_index] & 0x00FF);
00304
00305 if (print_pixel1)
00306
00307 video_buffer[video_index] = pixel1 |
00308 (video_buffer[video_index] & 0xFF00);
00309 }
00310 }
00311 }
00312
00324 void Graphics::PrintBitmap (int x, int y, int width, int height,
00325 const unsigned char* bitmap, int bgid,
00326 Screen::selector screen)
00327 {
00328 u16* video_buffer = bgGetGfxPtr(bgid);
00329
00330 for (int image_y = 0; image_y < height; ++image_y)
00331 {
00332 int image_x = 0;
00333 int index = image_y * width;
00334 for (; image_x < width-1; image_x += 2, index+=2)
00335 {
00336 bool print_pixel0 = true, print_pixel1 = true;
00337 u16 pixel0 = convert_color(bitmap[index], screen);
00338 print_pixel0 = (pixel0 != TRANSPARENT_COLOR);
00339 u16 pixel1 = convert_color(bitmap[index+1], screen);
00340 print_pixel1 = (pixel1 != TRANSPARENT_COLOR);
00341 int video_index = ((y + image_y) <<7) +
00342 ((x + image_x) >> 1);
00343
00344 if (print_pixel0 && print_pixel1)
00345 video_buffer[video_index] = pixel0 | (pixel1 << 8);
00346 else if (print_pixel0)
00347
00348 video_buffer[video_index] = pixel0 |
00349 (video_buffer[video_index] & 0xFF00);
00350
00351 else if (print_pixel1)
00352
00353 video_buffer[video_index] = (pixel1 << 8) |
00354 (video_buffer[video_index] & 0x00FF);
00355 }
00356 if (image_x == width-1)
00357 {
00358 bool print_pixel = true;
00359
00360 int index = image_y * width + image_x;
00361 u16 pixel = convert_color(bitmap[index], screen);
00362 print_pixel = (pixel != TRANSPARENT_COLOR);
00363 int video_index = ((y + image_y) <<7) +
00364 ((x + image_x) >> 1);
00365 if (print_pixel)
00366
00367 video_buffer[video_index] = pixel |
00368 (video_buffer[video_index] & 0xFF00);
00369 }
00370 }
00371 }
00372
00373 void Graphics::RedrawBgRegion (int x, int y,
00374 int region_width, int region_height,
00375 MainScreenMode::mode screen_mode,
00376 GameMode::mode game_mode,
00377 int bgid)
00378 {
00379 Graphics::PrintBitmapRegion(x, y, x, y, region_width, region_height,
00380 SCREEN_WIDTH, SCREEN_HEIGHT,
00381 GetBitmapPtr(screen_mode),
00382 RGB15(0,0,0), bgid, Screen::MAIN, false);
00383 }
00384
00385 void Graphics::RedrawBgRegion (int x, int y,
00386 int region_width, int region_height,
00387 SubScreenMode::mode screen_mode,
00388 GameMode::mode game_mode,
00389 int bgid)
00390 {
00391 Graphics::PrintBitmapRegion(x, y, x, y, region_width, region_height,
00392 SCREEN_WIDTH, SCREEN_HEIGHT,
00393 GetBitmapPtr(screen_mode, game_mode),
00394 RGB15(0,0,0), bgid, Screen::SUB, false);
00395 }
00396
00397 void Graphics::Fill (unsigned short color, Screen::selector screen)
00398 {
00399 if (screen == Screen::MAIN)
00400 dmaFillHalfWords(color, BG_PALETTE, 256*2);
00401 else
00402 dmaFillHalfWords(color, BG_PALETTE_SUB, 256*2);
00403 }
00404
00405 unsigned short Graphics::FindColor (unsigned short color,
00406 Screen::selector screen,
00407 unsigned short offset)
00408 {
00409 unsigned short i = offset;
00410 if (screen == Screen::MAIN)
00411 for (; i < 256 && BG_PALETTE[i] != color; ++i);
00412 else
00413 for (; i < 256 && BG_PALETTE_SUB[i] != color; ++i);
00414 return i;
00415 }
00416
00417 void Graphics::SetColors ()
00418 {
00419 black_color_main = FindColor (RGB15(0,0,0), Screen::MAIN);
00420 gray_color_main = FindColor (RGB15(15,15,15), Screen::MAIN);
00421 black_color_sub = FindColor (RGB15(0,0,0), Screen::SUB);
00422 gray_color_sub = FindColor (RGB15(15,15,15), Screen::SUB);
00423 }
00424
00425 const unsigned int* Graphics::GetBitmapPtr (MainScreenMode::mode screen_mode)
00426 {
00427 if (screen_mode == MainScreenMode::KANJI)
00428 return kanji_bgBitmap;
00429 if (screen_mode == MainScreenMode::SPLASH_SCREEN)
00430 return splash_main_bgBitmap;
00431 if (screen_mode == MainScreenMode::VERTICAL_TEXTBOXES)
00432 return kanji_bgBitmap;
00433 if (screen_mode == MainScreenMode::VERTICAL_TEXTBOXES_VISIBLE)
00434 return goi_bgBitmap;
00435
00436 return NULL;
00437 }
00438
00439 const unsigned short* Graphics::GetPalPtr (MainScreenMode::mode screen_mode)
00440 {
00441 if (screen_mode == MainScreenMode::KANJI)
00442 return kanji_bgPal;
00443 if (screen_mode == MainScreenMode::SPLASH_SCREEN)
00444 return splash_main_bgPal;
00445 if (screen_mode == MainScreenMode::VERTICAL_TEXTBOXES)
00446 return kanji_bgPal;
00447 if (screen_mode == MainScreenMode::VERTICAL_TEXTBOXES_VISIBLE)
00448 return goi_bgPal;
00449
00450 return NULL;
00451 }
00452
00453 const unsigned int* Graphics::GetBitmapPtr (SubScreenMode::mode screen_mode,
00454 GameMode::mode game_mode)
00455 {
00456 if (screen_mode == SubScreenMode::CARDS)
00457 return cards_options_sub_bgBitmap;
00458 if (screen_mode == SubScreenMode::KANJI_CHOOSE)
00459 return kanji_choose_options_sub_bgBitmap;
00460 if (screen_mode == SubScreenMode::VERTICAL_TEXTBOXES_CHOOSE)
00461 return vertical_textboxes_choose_options_bgBitmap;
00462 if (screen_mode == SubScreenMode::MAIN_MENU)
00463 return main_menu_bgBitmap;
00464 if (screen_mode == SubScreenMode::OPTIONS_GRADE_STROKES_ROMAJI)
00465 return options_grade_strokes_romaji_sub_bgBitmap;
00466 if (screen_mode == SubScreenMode::OPTIONS_ROMAJI)
00467 return options_romaji_sub_bgBitmap;
00468
00469 return NULL;
00470 }
00471
00472 const unsigned short* Graphics::GetPalPtr (SubScreenMode::mode screen_mode,
00473 GameMode::mode game_mode)
00474 {
00475 if (screen_mode == SubScreenMode::CARDS)
00476 return cards_options_sub_bgPal;
00477 if (screen_mode == SubScreenMode::KANJI_CHOOSE)
00478 return kanji_choose_options_sub_bgPal;
00479 if (screen_mode == SubScreenMode::VERTICAL_TEXTBOXES_CHOOSE)
00480 return vertical_textboxes_choose_options_bgPal;
00481 if (screen_mode == SubScreenMode::MAIN_MENU)
00482 return main_menu_bgPal;
00483 if (screen_mode == SubScreenMode::OPTIONS_GRADE_STROKES_ROMAJI)
00484 return options_grade_strokes_romaji_sub_bgPal;
00485 if (screen_mode == SubScreenMode::OPTIONS_ROMAJI)
00486 return options_romaji_sub_bgPal;
00487
00488 return NULL;
00489 }