372 lines
6.8 KiB
C
372 lines
6.8 KiB
C
/*
|
|
* PSXPaint
|
|
*/
|
|
|
|
/*
|
|
* Video memory layout:
|
|
*
|
|
* [0-639],[0-479] - Screen memory
|
|
* [640-895],[480-511] - Color Look Up Tables
|
|
* [640-643],[0-23] - Cursor Image (16x24) (4bpp - real width: 16)
|
|
* [992-1023],[0-31] - Cursor Dirty Rectangle (32x32)
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <psx.h>
|
|
#include <psxgpu.h>
|
|
#include "cursor.h"
|
|
|
|
int cursor_x = 0, cursor_y = 0, cursor_speed = 1;
|
|
int old_cursor_x, old_cursor_y;
|
|
volatile unsigned int speed_counter = 0;
|
|
int brush_type = 0;
|
|
|
|
unsigned int primitive_list[4000];
|
|
|
|
int paint_colors[20][3] = {
|
|
{ 0, 0, 0 }, // #0 Black
|
|
{ 255, 255, 255 }, // #1 White
|
|
{ 255, 0, 0 }, // #2 Red
|
|
{ 0, 255, 0 }, // #3 Green
|
|
{ 0, 0, 255 }, // #4 Blue
|
|
{ 255, 255, 0}, // #5 Yellow
|
|
{ 255, 0, 255}, // #6 Magenta (Fuchsia)
|
|
{ 0, 255, 255}, // #7 Aqua Green
|
|
{ 255, 128, 0}, // #8 Orange
|
|
{ 128, 255,0}, // #9 Lime Green
|
|
|
|
{ 192, 192,255},// #10 Sky Blue
|
|
{ 128,128,128}, // #11 Grey
|
|
{ 128, 0,0 }, // #12 Dark Red
|
|
{ 0, 128, 0}, // #13 Dark Green
|
|
{ 0, 0, 128}, // #14 Dark Blue
|
|
{ 128, 128, 0}, // #15 Dark Yellow
|
|
{ 128, 0, 128}, // #16 Purple
|
|
{ 0, 128, 128}, // #17 Dark Aqua
|
|
{ 128, 64, 0}, // #18 Brown
|
|
{ 64, 128, 0}, // #19 Dark Lime Green
|
|
|
|
/*{ 128, 0, 255}, // #10 Violet
|
|
{ 128,128,128}, // #11 Grey
|
|
{ 128, 0,0 }, // #12 Dark Red
|
|
{ 0, 128, 0}, // #13 Dark Green
|
|
{ 0, 0, 128}, // #14 Dark Blue
|
|
{ 192, 192,255},// #15 Sky Blue
|
|
{ 128, 128, 0}, // #16 Dark Yellow
|
|
{ 150, 75, 0}, // #17 Brown
|
|
{ 64, 64, 64}, // #18 Dark Grey
|
|
{ 128, 255,0}, // #19 Lime Green
|
|
*/
|
|
};
|
|
|
|
int current_color[3];
|
|
|
|
void sort_color_boxes()
|
|
{
|
|
GsRectangle colorbox;
|
|
int x, y, c=0;
|
|
|
|
for(y = 384; y < (384+32); y+=16)
|
|
{
|
|
for(x = 0; x < 640; x+=64)
|
|
{
|
|
colorbox.x = x;
|
|
colorbox.y = y;
|
|
colorbox.w = 64;
|
|
colorbox.h = 16;
|
|
colorbox.r = paint_colors[c][0];
|
|
colorbox.g = paint_colors[c][1];
|
|
colorbox.b = paint_colors[c][2];
|
|
colorbox.attribute = 0;
|
|
|
|
GsSortRectangle(&colorbox);
|
|
|
|
c++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void load_ui_graphics()
|
|
{
|
|
GsImage my_image;
|
|
|
|
GsImageFromTim(&my_image, cursor_tim);
|
|
GsUploadImage(&my_image);
|
|
}
|
|
|
|
void my_vblank_handler();
|
|
|
|
void my_vblank_handler()
|
|
{
|
|
speed_counter++;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
GsDispEnv my_dispenv;
|
|
GsDrawEnv my_drawenv;
|
|
GsSprite my_sprite;
|
|
GsRectangle colorbox;
|
|
GsDot my_dot;
|
|
unsigned short pad1;
|
|
unsigned int WasL2=0, WasR2=0, WasL1=0, WasR1=0, WasSelect = 0;
|
|
int x, y;
|
|
|
|
PSX_InitEx(PSX_INIT_NOBIOS);
|
|
GsInit();
|
|
GsClearMem();
|
|
SetVBlankHandler(my_vblank_handler);
|
|
|
|
// This has to be interlaced
|
|
GsSetVideoModeEx(640, 480, EXAMPLES_VMODE, 0, 1, 0);
|
|
|
|
my_dispenv.x = 0;
|
|
my_dispenv.y = 0;
|
|
|
|
GsSetDispEnv(&my_dispenv);
|
|
|
|
my_drawenv.dither = 0;
|
|
my_drawenv.draw_on_display = 1;
|
|
my_drawenv.x = 0;
|
|
my_drawenv.y = 0;
|
|
my_drawenv.w = 640;
|
|
my_drawenv.h = 512;
|
|
my_drawenv.ignore_mask = 0;
|
|
my_drawenv.set_mask = 0;
|
|
|
|
GsSetDrawEnv(&my_drawenv);
|
|
|
|
GsSetList(primitive_list);
|
|
|
|
load_ui_graphics();
|
|
while(GsIsDrawing());
|
|
|
|
colorbox.x = 0;
|
|
colorbox.y = 0;
|
|
colorbox.w = 640;
|
|
colorbox.h = 511;
|
|
colorbox.r = 255;
|
|
colorbox.g = 255;
|
|
colorbox.b = 255;
|
|
colorbox.attribute = 0;
|
|
|
|
GsSortRectangle(&colorbox);
|
|
|
|
sort_color_boxes();
|
|
|
|
|
|
my_sprite.x = 0;
|
|
my_sprite.y = 0;
|
|
my_sprite.tpage = 10;
|
|
my_sprite.u = 0;
|
|
my_sprite.v = 0;
|
|
my_sprite.attribute = 0;
|
|
my_sprite.cx = 640;
|
|
my_sprite.cy = 480;
|
|
my_sprite.r = my_sprite.g = my_sprite.b = NORMAL_LUMINOSITY;
|
|
my_sprite.scalex = my_sprite.scaley = 0;
|
|
my_sprite.w = 16;
|
|
my_sprite.h = 24;
|
|
|
|
GsDrawList();
|
|
while(GsIsDrawing());
|
|
|
|
// Backup 32x32 area
|
|
MoveImage(cursor_x, cursor_y, 992, 0, 32, 32);
|
|
|
|
my_dot.attribute = 0;
|
|
|
|
while(1)
|
|
{
|
|
while(speed_counter)
|
|
{
|
|
old_cursor_x = cursor_x;
|
|
old_cursor_y = cursor_y;
|
|
|
|
// Restore 32x32 area
|
|
MoveImage(992, 0, old_cursor_x, old_cursor_y, 32, 32);
|
|
while(GsIsDrawing());
|
|
|
|
PSX_ReadPad(&pad1, NULL);
|
|
|
|
if(pad1 & PAD_LEFT)
|
|
cursor_x-=cursor_speed;
|
|
|
|
if(pad1 & PAD_RIGHT)
|
|
cursor_x+=cursor_speed;
|
|
|
|
if(pad1 & PAD_UP)
|
|
cursor_y-=cursor_speed;
|
|
|
|
if(pad1 & PAD_DOWN)
|
|
cursor_y+=cursor_speed;
|
|
|
|
if(cursor_x <= 0)
|
|
cursor_x = 0;
|
|
|
|
if(pad1 & PAD_CROSS)
|
|
{
|
|
if(cursor_y >= 384)
|
|
{
|
|
y = (cursor_y - 384) >> 4;
|
|
x = cursor_x >> 6;
|
|
|
|
current_color[0] = paint_colors[(y * 10)+x][0];
|
|
current_color[1] = paint_colors[(y * 10)+x][1];
|
|
current_color[2] = paint_colors[(y * 10)+x][2];
|
|
}
|
|
else
|
|
{
|
|
|
|
switch(brush_type)
|
|
{
|
|
case 0:
|
|
if(cursor_y >= 384)
|
|
{
|
|
break;
|
|
}
|
|
|
|
my_dot.r = current_color[0];
|
|
my_dot.g = current_color[1];
|
|
my_dot.b = current_color[2];
|
|
my_dot.x = cursor_x;
|
|
my_dot.y = cursor_y;
|
|
|
|
GsSortDot(&my_dot);
|
|
break;
|
|
case 1:
|
|
if(cursor_y >= 380)
|
|
{
|
|
break;
|
|
}
|
|
|
|
my_dot.r = current_color[0];
|
|
my_dot.g = current_color[1];
|
|
my_dot.b = current_color[2];
|
|
my_dot.x = cursor_x + 1;
|
|
my_dot.y = cursor_y;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.x++;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.y++;
|
|
my_dot.x-=2;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.x++;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.x++;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.x++;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.y++;
|
|
my_dot.x-=2;
|
|
|
|
GsSortDot(&my_dot);
|
|
|
|
my_dot.x++;
|
|
|
|
GsSortDot(&my_dot);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
GsDrawList();
|
|
while(GsIsDrawing());
|
|
}
|
|
|
|
if((pad1 & PAD_R2) && !WasR2)
|
|
{
|
|
cursor_speed++;
|
|
WasR2 = 1;
|
|
}
|
|
|
|
if((pad1 & PAD_L2) && !WasL2)
|
|
{
|
|
cursor_speed--;
|
|
WasL2 = 1;
|
|
}
|
|
|
|
if(!(pad1 & PAD_R2))
|
|
WasR2 = 0;
|
|
|
|
if(!(pad1 & PAD_L2))
|
|
WasL2 = 0;
|
|
|
|
if((pad1 & PAD_R1) && !WasR1)
|
|
{
|
|
brush_type++;
|
|
WasR1 = 1;
|
|
}
|
|
|
|
if((pad1 & PAD_L1) && !WasL1)
|
|
{
|
|
brush_type--;
|
|
WasL1 = 1;
|
|
}
|
|
|
|
if((pad1 & PAD_SELECT) && !WasSelect)
|
|
{
|
|
my_sprite.attribute ^= (ENABLE_TRANS | TRANS_MODE(0));
|
|
my_dot.attribute ^= (ENABLE_TRANS | TRANS_MODE(0));
|
|
WasSelect = 1;
|
|
}
|
|
|
|
if(!(pad1 & PAD_SELECT))
|
|
WasSelect = 0;
|
|
|
|
if(!(pad1 & PAD_R1))
|
|
WasR1 = 0;
|
|
|
|
if(!(pad1 & PAD_L1))
|
|
WasL1 = 0;
|
|
|
|
if(cursor_speed <= 0)
|
|
cursor_speed = 1;
|
|
|
|
if(cursor_speed >= 8)
|
|
cursor_speed = 7;
|
|
|
|
if(brush_type <= 0)
|
|
brush_type = 0;
|
|
|
|
if(brush_type > 1)
|
|
brush_type = 1;
|
|
|
|
// Backup 32x32 area
|
|
MoveImage(cursor_x, cursor_y, 992, 0, 32, 32);
|
|
while(GsIsDrawing());
|
|
|
|
// if(cursor_x != old_cursor_x || cursor_y != old_cursor_y)
|
|
// {
|
|
// printf("cx = %d, cy = %d, cursor_speed = %d, brush_type = %d\n",
|
|
// cursor_x, cursor_y, cursor_speed, brush_type);
|
|
|
|
|
|
|
|
|
|
|
|
my_sprite.x = cursor_x;
|
|
my_sprite.y = cursor_y;
|
|
GsSortSimpleSprite(&my_sprite);
|
|
|
|
GsDrawList();
|
|
while(GsIsDrawing());
|
|
// }
|
|
|
|
speed_counter--;
|
|
}
|
|
}
|
|
}
|