mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-19 09:18:02 +00:00
Add Rotated OSD
This commit is contained in:
parent
a453cc39f3
commit
7a925876d8
Binary file not shown.
@ -41,7 +41,7 @@
|
||||
# ========================
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 15.1.0
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:45:13 JUNE 17,2016"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
|
||||
# Pin & Location Assignments
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
`define BUILD_DATE "180925"
|
||||
`define BUILD_TIME "183755"
|
||||
`define BUILD_DATE "190303"
|
||||
`define BUILD_TIME "191855"
|
||||
|
||||
@ -21,11 +21,11 @@ module burger_time_mist
|
||||
|
||||
localparam CONF_STR = {
|
||||
"BurgerTime;;",
|
||||
"O2,Joystick Control,Upright,Normal;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||
"T6,Reset;",
|
||||
"V,v1.00.",`BUILD_DATE
|
||||
};
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
@ -42,19 +42,18 @@ assign LED = 1;
|
||||
wire clk_12, clk_6, clk_24;
|
||||
wire pll_locked;
|
||||
|
||||
pll pll
|
||||
(
|
||||
pll pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(clk_24),
|
||||
.c1(clk_12),
|
||||
.c2(clk_6)
|
||||
);
|
||||
);
|
||||
|
||||
wire m_up = status[2] ? kbjoy[6] | joystick_0[1] | joystick_1[1] : kbjoy[4] | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = status[2] ? kbjoy[7] | joystick_0[0] | joystick_1[0] : kbjoy[5] | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = status[2] ? kbjoy[5] | joystick_0[2] | joystick_1[2] : kbjoy[6] | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = status[2] ? kbjoy[4] | joystick_0[3] | joystick_1[3] : kbjoy[7] | joystick_0[0] | joystick_1[0];
|
||||
wire m_up = ~status[2] ? kbjoy[6] | joystick_0[1] | joystick_1[1] : kbjoy[4] | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = ~status[2] ? kbjoy[7] | joystick_0[0] | joystick_1[0] : kbjoy[5] | joystick_0[2] | joystick_1[2];
|
||||
wire m_left = ~status[2] ? kbjoy[5] | joystick_0[2] | joystick_1[2] : kbjoy[6] | joystick_0[1] | joystick_1[1];
|
||||
wire m_right = ~status[2] ? kbjoy[4] | joystick_0[3] | joystick_1[3] : kbjoy[7] | joystick_0[0] | joystick_1[0];
|
||||
|
||||
wire m_fire = kbjoy[0] | joystick_0[4] | joystick_1[4];
|
||||
wire m_start1 = kbjoy[1];
|
||||
@ -86,11 +85,11 @@ burger_time burger_time(
|
||||
.down2(m_down),
|
||||
.up2(m_up),
|
||||
.dbg_cpu_addr()
|
||||
);
|
||||
);
|
||||
|
||||
wire [10:0] audio;
|
||||
|
||||
dac dac (
|
||||
dac dac(
|
||||
.clk_i(clk_24),
|
||||
.res_n_i(1),
|
||||
.dac_i(audio),
|
||||
@ -104,8 +103,10 @@ wire [2:0] r, g;
|
||||
wire [1:0] b;
|
||||
wire blankn;
|
||||
|
||||
video_mixer #(.LINE_LENGTH(320), .HALF_DEPTH(1)) video_mixer
|
||||
(
|
||||
video_mixer #(
|
||||
.LINE_LENGTH(320),
|
||||
.HALF_DEPTH(1))
|
||||
video_mixer(
|
||||
.clk_sys(clk_24),
|
||||
.ce_pix(clk_6),
|
||||
.ce_pix_actual(clk_6),
|
||||
@ -125,13 +126,16 @@ video_mixer #(.LINE_LENGTH(320), .HALF_DEPTH(1)) video_mixer
|
||||
.scandoubler_disable(scandoubler_disable),
|
||||
.scanlines(scandoubler_disable ? 2'b00 : {status[4:3] == 3, status[4:3] == 2}),
|
||||
.hq2x(status[4:3]==1),
|
||||
.rotate({1'b1,status[2]}),
|
||||
.ypbpr(ypbpr),
|
||||
.ypbpr_full(1),
|
||||
.line_start(0),
|
||||
.mono(0)
|
||||
);
|
||||
);
|
||||
|
||||
mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
|
||||
(
|
||||
mist_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
mist_io(
|
||||
.clk_sys (clk_24 ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_SCK (SPI_SCK ),
|
||||
@ -148,7 +152,7 @@ mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
);
|
||||
|
||||
keyboard keyboard(
|
||||
.clk(clk_24),
|
||||
|
||||
@ -11,13 +11,15 @@ module osd (
|
||||
input SPI_SS3,
|
||||
input SPI_DI,
|
||||
|
||||
input [1:0] rotate, //[0] - rotate [1] - left or right
|
||||
|
||||
// VGA signals coming from core
|
||||
input [5:0] R_in,
|
||||
input [5:0] G_in,
|
||||
input [5:0] B_in,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
|
||||
// VGA signals going to video connector
|
||||
output [5:0] R_out,
|
||||
output [5:0] G_out,
|
||||
@ -59,7 +61,7 @@ always@(posedge SPI_SCK, posedge SPI_SS3) begin
|
||||
|
||||
if(cnt == 7) begin
|
||||
cmd <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
|
||||
// lower three command bits are line address
|
||||
bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
|
||||
|
||||
@ -91,7 +93,7 @@ reg [9:0] vs_low, vs_high;
|
||||
wire vs_pol = vs_high < vs_low;
|
||||
wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
|
||||
|
||||
wire doublescan = (dsp_height>350);
|
||||
wire doublescan = (dsp_height>350);
|
||||
|
||||
reg ce_pix;
|
||||
always @(negedge clk_sys) begin
|
||||
@ -124,13 +126,13 @@ always @(posedge clk_sys) begin
|
||||
hsD2 <= hsD;
|
||||
|
||||
// falling edge of HSync
|
||||
if(!hsD && hsD2) begin
|
||||
if(!hsD && hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_high <= h_cnt;
|
||||
end
|
||||
|
||||
// rising edge of HSync
|
||||
else if(hsD && !hsD2) begin
|
||||
else if(hsD && !hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_low <= h_cnt;
|
||||
v_cnt <= v_cnt + 1'd1;
|
||||
@ -142,13 +144,13 @@ always @(posedge clk_sys) begin
|
||||
vsD2 <= vsD;
|
||||
|
||||
// falling edge of VSync
|
||||
if(!vsD && vsD2) begin
|
||||
if(!vsD && vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_high <= v_cnt;
|
||||
end
|
||||
|
||||
// rising edge of VSync
|
||||
else if(vsD && !vsD2) begin
|
||||
else if(vsD && !vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_low <= v_cnt;
|
||||
end
|
||||
@ -160,17 +162,30 @@ wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
|
||||
wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
|
||||
wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<<doublescan))>> 1) + OSD_Y_OFFSET;
|
||||
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start;
|
||||
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
|
||||
wire [9:0] osd_hcnt_next = osd_hcnt + 2'd1; // one pixel offset for osd pixel
|
||||
wire [9:0] osd_hcnt_next2 = osd_hcnt + 2'd2; // two pixel offset for osd byte address register
|
||||
|
||||
wire osd_de = osd_enable &&
|
||||
wire osd_de = osd_enable &&
|
||||
(HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) &&
|
||||
(VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
|
||||
|
||||
reg [7:0] osd_byte;
|
||||
always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}];
|
||||
reg [10:0] osd_buffer_addr;
|
||||
wire [7:0] osd_byte = osd_buffer[osd_buffer_addr];
|
||||
reg osd_pixel;
|
||||
|
||||
wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
always @(posedge clk_sys) begin
|
||||
if(ce_pix) begin
|
||||
osd_buffer_addr <= rotate[0] ? {rotate[1] ? osd_hcnt_next2[7:5] : ~osd_hcnt_next2[7:5],
|
||||
rotate[1] ? (doublescan ? ~osd_vcnt[7:0] : ~{osd_vcnt[6:0], 1'b0}) :
|
||||
(doublescan ? osd_vcnt[7:0] : {osd_vcnt[6:0], 1'b0})} :
|
||||
{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt_next2[7:0]};
|
||||
|
||||
osd_pixel <= rotate[0] ? osd_byte[rotate[1] ? osd_hcnt_next[4:2] : ~osd_hcnt_next[4:2]] :
|
||||
osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
end
|
||||
end
|
||||
|
||||
assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
|
||||
assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
|
||||
|
||||
@ -60,7 +60,7 @@ module video_mixer
|
||||
|
||||
// 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space)
|
||||
input ypbpr_full,
|
||||
|
||||
input [1:0] rotate, //[0] - rotate [1] - left or right
|
||||
// color
|
||||
input [DWIDTH:0] R,
|
||||
input [DWIDTH:0] G,
|
||||
@ -182,6 +182,7 @@ osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
|
||||
.B_in(b_out),
|
||||
.HSync(hs),
|
||||
.VSync(vs),
|
||||
.rotate(rotate),
|
||||
|
||||
.R_out(red),
|
||||
.G_out(green),
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
-- https://sourceforge.net/projects/darfpga/files/Software%20VHDL/burnin_rubber/
|
||||
---------------------------------------------------------------------------------
|
||||
--
|
||||
-- Only controls are rotated on VGA output.
|
||||
-- Only controls and OSD are rotated on VGA output.
|
||||
--
|
||||
--
|
||||
-- Keyboard inputs :
|
||||
|
||||
Binary file not shown.
@ -1,2 +1,2 @@
|
||||
`define BUILD_DATE "171226"
|
||||
`define BUILD_TIME "145326"
|
||||
`define BUILD_DATE "190303"
|
||||
`define BUILD_TIME "192419"
|
||||
|
||||
@ -21,10 +21,10 @@ module burnin_rubber_mist
|
||||
|
||||
localparam CONF_STR = {
|
||||
"Burn.Rubb;;",
|
||||
"O2,Joystick Control,Upright,Normal;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||
"T6,Reset;",
|
||||
"V,v1.00.",`BUILD_DATE
|
||||
"V,v1.10.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire [31:0] status;
|
||||
@ -42,15 +42,14 @@ assign LED = 1;
|
||||
wire clk_48, clk_12, clk_6, clk_24;
|
||||
wire pll_locked;
|
||||
|
||||
pll pll
|
||||
(
|
||||
pll pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(clk_48),
|
||||
.c1(clk_12),
|
||||
.c2(clk_6),
|
||||
.c3(clk_24)
|
||||
);
|
||||
);
|
||||
|
||||
wire m_up = ~status[2] ? kbjoy[6] | joystick_0[1] | joystick_1[1] : kbjoy[4] | joystick_0[3] | joystick_1[3];
|
||||
wire m_down = ~status[2] ? kbjoy[7] | joystick_0[0] | joystick_1[0] : kbjoy[5] | joystick_0[2] | joystick_1[2];
|
||||
@ -87,11 +86,11 @@ burnin_rubber burnin_rubber(
|
||||
.down2(m_down),
|
||||
.up2(m_up),
|
||||
.dbg_cpu_addr()
|
||||
);
|
||||
);
|
||||
|
||||
wire [10:0] audio;
|
||||
|
||||
dac dac (
|
||||
dac dac(
|
||||
.clk_i(clk_48),
|
||||
.res_n_i(1),
|
||||
.dac_i(audio),
|
||||
@ -105,8 +104,10 @@ wire [2:0] r, g;
|
||||
wire [1:0] b;
|
||||
wire blankn;
|
||||
|
||||
video_mixer #(.LINE_LENGTH(320), .HALF_DEPTH(1)) video_mixer
|
||||
(
|
||||
video_mixer #(
|
||||
.LINE_LENGTH(320),
|
||||
.HALF_DEPTH(1))
|
||||
video_mixer(
|
||||
.clk_sys(clk_48),
|
||||
.ce_pix(clk_6),
|
||||
.ce_pix_actual(clk_6),
|
||||
@ -123,16 +124,19 @@ video_mixer #(.LINE_LENGTH(320), .HALF_DEPTH(1)) video_mixer
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.rotate({1'b1,status[2]}),
|
||||
.scandoubler_disable(scandoubler_disable),
|
||||
.scanlines(scandoubler_disable ? 2'b00 : {status[4:3] == 3, status[4:3] == 2}),
|
||||
.hq2x(status[4:3]==1),
|
||||
.ypbpr(ypbpr),
|
||||
.ypbpr_full(1),
|
||||
.line_start(0),
|
||||
.mono(0)
|
||||
);
|
||||
);
|
||||
|
||||
mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
|
||||
(
|
||||
mist_io #(
|
||||
.STRLEN(($size(CONF_STR)>>3)))
|
||||
mist_io(
|
||||
.clk_sys (clk_48 ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_SCK (SPI_SCK ),
|
||||
@ -149,7 +153,7 @@ mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
|
||||
.joystick_0 (joystick_0 ),
|
||||
.joystick_1 (joystick_1 ),
|
||||
.status (status )
|
||||
);
|
||||
);
|
||||
|
||||
keyboard keyboard(
|
||||
.clk(clk_48),
|
||||
@ -159,7 +163,6 @@ keyboard keyboard(
|
||||
.joystick(kbjoy)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
@ -11,13 +11,15 @@ module osd (
|
||||
input SPI_SS3,
|
||||
input SPI_DI,
|
||||
|
||||
input [1:0] rotate, //[0] - rotate [1] - left or right
|
||||
|
||||
// VGA signals coming from core
|
||||
input [5:0] R_in,
|
||||
input [5:0] G_in,
|
||||
input [5:0] B_in,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
|
||||
// VGA signals going to video connector
|
||||
output [5:0] R_out,
|
||||
output [5:0] G_out,
|
||||
@ -59,7 +61,7 @@ always@(posedge SPI_SCK, posedge SPI_SS3) begin
|
||||
|
||||
if(cnt == 7) begin
|
||||
cmd <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
|
||||
// lower three command bits are line address
|
||||
bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
|
||||
|
||||
@ -91,7 +93,7 @@ reg [9:0] vs_low, vs_high;
|
||||
wire vs_pol = vs_high < vs_low;
|
||||
wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
|
||||
|
||||
wire doublescan = (dsp_height>350);
|
||||
wire doublescan = (dsp_height>350);
|
||||
|
||||
reg ce_pix;
|
||||
always @(negedge clk_sys) begin
|
||||
@ -124,13 +126,13 @@ always @(posedge clk_sys) begin
|
||||
hsD2 <= hsD;
|
||||
|
||||
// falling edge of HSync
|
||||
if(!hsD && hsD2) begin
|
||||
if(!hsD && hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_high <= h_cnt;
|
||||
end
|
||||
|
||||
// rising edge of HSync
|
||||
else if(hsD && !hsD2) begin
|
||||
else if(hsD && !hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_low <= h_cnt;
|
||||
v_cnt <= v_cnt + 1'd1;
|
||||
@ -142,13 +144,13 @@ always @(posedge clk_sys) begin
|
||||
vsD2 <= vsD;
|
||||
|
||||
// falling edge of VSync
|
||||
if(!vsD && vsD2) begin
|
||||
if(!vsD && vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_high <= v_cnt;
|
||||
end
|
||||
|
||||
// rising edge of VSync
|
||||
else if(vsD && !vsD2) begin
|
||||
else if(vsD && !vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_low <= v_cnt;
|
||||
end
|
||||
@ -160,17 +162,30 @@ wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
|
||||
wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
|
||||
wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<<doublescan))>> 1) + OSD_Y_OFFSET;
|
||||
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start;
|
||||
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
|
||||
wire [9:0] osd_hcnt_next = osd_hcnt + 2'd1; // one pixel offset for osd pixel
|
||||
wire [9:0] osd_hcnt_next2 = osd_hcnt + 2'd2; // two pixel offset for osd byte address register
|
||||
|
||||
wire osd_de = osd_enable &&
|
||||
wire osd_de = osd_enable &&
|
||||
(HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) &&
|
||||
(VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
|
||||
|
||||
reg [7:0] osd_byte;
|
||||
always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}];
|
||||
reg [10:0] osd_buffer_addr;
|
||||
wire [7:0] osd_byte = osd_buffer[osd_buffer_addr];
|
||||
reg osd_pixel;
|
||||
|
||||
wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
always @(posedge clk_sys) begin
|
||||
if(ce_pix) begin
|
||||
osd_buffer_addr <= rotate[0] ? {rotate[1] ? osd_hcnt_next2[7:5] : ~osd_hcnt_next2[7:5],
|
||||
rotate[1] ? (doublescan ? ~osd_vcnt[7:0] : ~{osd_vcnt[6:0], 1'b0}) :
|
||||
(doublescan ? osd_vcnt[7:0] : {osd_vcnt[6:0], 1'b0})} :
|
||||
{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt_next2[7:0]};
|
||||
|
||||
osd_pixel <= rotate[0] ? osd_byte[rotate[1] ? osd_hcnt_next[4:2] : ~osd_hcnt_next[4:2]] :
|
||||
osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
end
|
||||
end
|
||||
|
||||
assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
|
||||
assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
|
||||
|
||||
@ -60,7 +60,7 @@ module video_mixer
|
||||
|
||||
// 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space)
|
||||
input ypbpr_full,
|
||||
|
||||
input [1:0] rotate, //[0] - rotate [1] - left or right
|
||||
// color
|
||||
input [DWIDTH:0] R,
|
||||
input [DWIDTH:0] G,
|
||||
@ -182,6 +182,7 @@ osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
|
||||
.B_in(b_out),
|
||||
.HSync(hs),
|
||||
.VSync(vs),
|
||||
.rotate(rotate),
|
||||
|
||||
.R_out(red),
|
||||
.G_out(green),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user